32
32
33
33
#include " core/debugger/engine_debugger.h"
34
34
#include " core/io/marshalls.h"
35
- #include " core/multiplayer/multiplayer_replicator.h"
36
35
#include " core/multiplayer/rpc_manager.h"
37
36
#include " scene/main/node.h"
38
37
42
41
#include " core/os/os.h"
43
42
#endif
44
43
44
+ MultiplayerReplicationInterface *(*MultiplayerAPI::create_default_replication_interface)(MultiplayerAPI *p_multiplayer) = nullptr ;
45
+
45
46
#ifdef DEBUG_ENABLED
46
47
void MultiplayerAPI::profile_bandwidth (const String &p_inout, int p_size) {
47
48
if (EngineDebugger::is_profiling (" multiplayer" )) {
@@ -74,24 +75,21 @@ void MultiplayerAPI::poll() {
74
75
Error err = multiplayer_peer->get_packet (&packet, len);
75
76
if (err != OK) {
76
77
ERR_PRINT (" Error getting packet!" );
77
- break ; // Something is wrong!
78
+ return ; // Something is wrong!
78
79
}
79
80
80
81
remote_sender_id = sender;
81
82
_process_packet (sender, packet, len);
82
83
remote_sender_id = 0 ;
83
84
84
85
if (!multiplayer_peer.is_valid ()) {
85
- break ; // It's also possible that a packet or RPC caused a disconnection, so also check here.
86
+ return ; // It's also possible that a packet or RPC caused a disconnection, so also check here.
86
87
}
87
88
}
88
- if (multiplayer_peer.is_valid () && multiplayer_peer->get_connection_status () == MultiplayerPeer::CONNECTION_CONNECTED) {
89
- replicator->poll ();
90
- }
89
+ replicator->on_network_process ();
91
90
}
92
91
93
92
void MultiplayerAPI::clear () {
94
- replicator->clear ();
95
93
connected_peers.clear ();
96
94
path_get_cache.clear ();
97
95
path_send_cache.clear ();
@@ -133,6 +131,7 @@ void MultiplayerAPI::set_multiplayer_peer(const Ref<MultiplayerPeer> &p_peer) {
133
131
multiplayer_peer->connect (" connection_failed" , callable_mp (this , &MultiplayerAPI::_connection_failed));
134
132
multiplayer_peer->connect (" server_disconnected" , callable_mp (this , &MultiplayerAPI::_server_disconnected));
135
133
}
134
+ replicator->on_reset ();
136
135
}
137
136
138
137
Ref<MultiplayerPeer> MultiplayerAPI::get_multiplayer_peer () const {
@@ -167,13 +166,13 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_
167
166
_process_raw (p_from, p_packet, p_packet_len);
168
167
} break ;
169
168
case NETWORK_COMMAND_SPAWN: {
170
- replicator->process_spawn_despawn (p_from, p_packet, p_packet_len, true );
169
+ replicator->on_spawn_receive (p_from, p_packet, p_packet_len);
171
170
} break ;
172
171
case NETWORK_COMMAND_DESPAWN: {
173
- replicator->process_spawn_despawn (p_from, p_packet, p_packet_len, false );
172
+ replicator->on_despawn_receive (p_from, p_packet, p_packet_len);
174
173
} break ;
175
174
case NETWORK_COMMAND_SYNC: {
176
- replicator->process_sync (p_from, p_packet, p_packet_len);
175
+ replicator->on_sync_receive (p_from, p_packet, p_packet_len);
177
176
} break ;
178
177
}
179
178
}
@@ -324,7 +323,7 @@ bool MultiplayerAPI::_send_confirm_path(Node *p_node, NodePath p_path, PathSentC
324
323
#define ENCODE_16 1 << 5
325
324
#define ENCODE_32 2 << 5
326
325
#define ENCODE_64 3 << 5
327
- Error MultiplayerAPI::encode_and_compress_variant (const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
326
+ Error MultiplayerAPI::encode_and_compress_variant (const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_allow_object_decoding ) {
328
327
// Unreachable because `VARIANT_MAX` == 27 and `ENCODE_VARIANT_MASK` == 31
329
328
CRASH_COND (p_variant.get_type () > VARIANT_META_TYPE_MASK);
330
329
@@ -385,7 +384,7 @@ Error MultiplayerAPI::encode_and_compress_variant(const Variant &p_variant, uint
385
384
} break ;
386
385
default :
387
386
// Any other case is not yet compressed.
388
- Error err = encode_variant (p_variant, r_buffer, r_len, allow_object_decoding );
387
+ Error err = encode_variant (p_variant, r_buffer, r_len, p_allow_object_decoding );
389
388
if (err != OK) {
390
389
return err;
391
390
}
@@ -399,7 +398,7 @@ Error MultiplayerAPI::encode_and_compress_variant(const Variant &p_variant, uint
399
398
return OK;
400
399
}
401
400
402
- Error MultiplayerAPI::decode_and_decompress_variant (Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len) {
401
+ Error MultiplayerAPI::decode_and_decompress_variant (Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len, bool p_allow_object_decoding ) {
403
402
const uint8_t *buf = p_buffer;
404
403
int len = p_len;
405
404
@@ -458,7 +457,7 @@ Error MultiplayerAPI::decode_and_decompress_variant(Variant &r_variant, const ui
458
457
}
459
458
} break ;
460
459
default :
461
- Error err = decode_variant (r_variant, p_buffer, p_len, r_len, allow_object_decoding );
460
+ Error err = decode_variant (r_variant, p_buffer, p_len, r_len, p_allow_object_decoding );
462
461
if (err != OK) {
463
462
return err;
464
463
}
@@ -467,17 +466,84 @@ Error MultiplayerAPI::decode_and_decompress_variant(Variant &r_variant, const ui
467
466
return OK;
468
467
}
469
468
469
+ Error MultiplayerAPI::encode_and_compress_variants (const Variant **p_variants, int p_count, uint8_t *p_buffer, int &r_len, bool *r_raw, bool p_allow_object_decoding) {
470
+ r_len = 0 ;
471
+ int size = 0 ;
472
+
473
+ if (p_count == 0 ) {
474
+ if (r_raw) {
475
+ *r_raw = true ;
476
+ }
477
+ return OK;
478
+ }
479
+
480
+ // Try raw encoding optimization.
481
+ if (r_raw && p_count == 1 ) {
482
+ *r_raw = false ;
483
+ const Variant &v = *(p_variants[0 ]);
484
+ if (v.get_type () == Variant::PACKED_BYTE_ARRAY) {
485
+ *r_raw = true ;
486
+ const PackedByteArray pba = v;
487
+ if (p_buffer) {
488
+ memcpy (p_buffer, pba.ptr (), pba.size ());
489
+ }
490
+ r_len += pba.size ();
491
+ } else {
492
+ encode_and_compress_variant (v, p_buffer, size, p_allow_object_decoding);
493
+ r_len += size;
494
+ }
495
+ return OK;
496
+ }
497
+
498
+ // Regular encoding.
499
+ for (int i = 0 ; i < p_count; i++) {
500
+ const Variant &v = *(p_variants[i]);
501
+ encode_and_compress_variant (v, p_buffer ? p_buffer + r_len : nullptr , size, p_allow_object_decoding);
502
+ r_len += size;
503
+ }
504
+ return OK;
505
+ }
506
+
507
+ Error MultiplayerAPI::decode_and_decompress_variants (Vector<Variant> &r_variants, const uint8_t *p_buffer, int p_len, int &r_len, bool p_raw, bool p_allow_object_decoding) {
508
+ r_len = 0 ;
509
+ int argc = r_variants.size ();
510
+ if (argc == 0 && p_raw) {
511
+ return OK;
512
+ }
513
+ ERR_FAIL_COND_V (p_raw && argc != 1 , ERR_INVALID_DATA);
514
+ if (p_raw) {
515
+ r_len = p_len;
516
+ PackedByteArray pba;
517
+ pba.resize (p_len);
518
+ memcpy (pba.ptrw (), p_buffer, p_len);
519
+ r_variants.write [0 ] = pba;
520
+ return OK;
521
+ }
522
+
523
+ Vector<Variant> args;
524
+ Vector<const Variant *> argp;
525
+ args.resize (argc);
526
+
527
+ for (int i = 0 ; i < argc; i++) {
528
+ ERR_FAIL_COND_V_MSG (r_len >= p_len, ERR_INVALID_DATA, " Invalid packet received. Size too small." );
529
+
530
+ int vlen;
531
+ Error err = MultiplayerAPI::decode_and_decompress_variant (r_variants.write [i], &p_buffer[r_len], p_len - r_len, &vlen, p_allow_object_decoding);
532
+ ERR_FAIL_COND_V_MSG (err != OK, err, " Invalid packet received. Unable to decode state variable." );
533
+ r_len += vlen;
534
+ }
535
+ return OK;
536
+ }
537
+
470
538
void MultiplayerAPI::_add_peer (int p_id) {
471
539
connected_peers.insert (p_id);
472
540
path_get_cache.insert (p_id, PathGetCache ());
473
- if (is_server ()) {
474
- replicator->spawn_all (p_id);
475
- }
541
+ replicator->on_peer_change (p_id, true );
476
542
emit_signal (SNAME (" peer_connected" ), p_id);
477
543
}
478
544
479
545
void MultiplayerAPI::_del_peer (int p_id) {
480
- connected_peers. erase (p_id);
546
+ replicator-> on_peer_change (p_id, false );
481
547
// Cleanup get cache.
482
548
path_get_cache.erase (p_id);
483
549
// Cleanup sent cache.
@@ -488,6 +554,7 @@ void MultiplayerAPI::_del_peer(int p_id) {
488
554
PathSentCache *psc = path_send_cache.getptr (E);
489
555
psc->confirmed_peers .erase (p_id);
490
556
}
557
+ connected_peers.erase (p_id);
491
558
emit_signal (SNAME (" peer_disconnected" ), p_id);
492
559
}
493
560
@@ -500,6 +567,7 @@ void MultiplayerAPI::_connection_failed() {
500
567
}
501
568
502
569
void MultiplayerAPI::_server_disconnected () {
570
+ replicator->on_reset ();
503
571
emit_signal (SNAME (" server_disconnected" ));
504
572
}
505
573
@@ -612,14 +680,26 @@ bool MultiplayerAPI::is_object_decoding_allowed() const {
612
680
return allow_object_decoding;
613
681
}
614
682
615
- void MultiplayerAPI::scene_enter_exit_notify (const String &p_scene, Node *p_node, bool p_enter) {
616
- replicator->scene_enter_exit_notify (p_scene, p_node, p_enter);
617
- }
618
-
619
683
void MultiplayerAPI::rpcp (Node *p_node, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) {
620
684
rpc_manager->rpcp (p_node, p_peer_id, p_method, p_arg, p_argcount);
621
685
}
622
686
687
+ Error MultiplayerAPI::spawn (Object *p_object, Variant p_config) {
688
+ return replicator->on_spawn (p_object, p_config);
689
+ }
690
+
691
+ Error MultiplayerAPI::despawn (Object *p_object, Variant p_config) {
692
+ return replicator->on_despawn (p_object, p_config);
693
+ }
694
+
695
+ Error MultiplayerAPI::replication_start (Object *p_object, Variant p_config) {
696
+ return replicator->on_replication_start (p_object, p_config);
697
+ }
698
+
699
+ Error MultiplayerAPI::replication_stop (Object *p_object, Variant p_config) {
700
+ return replicator->on_replication_stop (p_object, p_config);
701
+ }
702
+
623
703
void MultiplayerAPI::_bind_methods () {
624
704
ClassDB::bind_method (D_METHOD (" set_root_node" , " node" ), &MultiplayerAPI::set_root_node);
625
705
ClassDB::bind_method (D_METHOD (" get_root_node" ), &MultiplayerAPI::get_root_node);
@@ -638,14 +718,12 @@ void MultiplayerAPI::_bind_methods() {
638
718
ClassDB::bind_method (D_METHOD (" is_refusing_new_connections" ), &MultiplayerAPI::is_refusing_new_connections);
639
719
ClassDB::bind_method (D_METHOD (" set_allow_object_decoding" , " enable" ), &MultiplayerAPI::set_allow_object_decoding);
640
720
ClassDB::bind_method (D_METHOD (" is_object_decoding_allowed" ), &MultiplayerAPI::is_object_decoding_allowed);
641
- ClassDB::bind_method (D_METHOD (" get_replicator" ), &MultiplayerAPI::get_replicator);
642
721
643
722
ADD_PROPERTY (PropertyInfo (Variant::BOOL, " allow_object_decoding" ), " set_allow_object_decoding" , " is_object_decoding_allowed" );
644
723
ADD_PROPERTY (PropertyInfo (Variant::BOOL, " refuse_new_connections" ), " set_refuse_new_connections" , " is_refusing_new_connections" );
645
724
ADD_PROPERTY (PropertyInfo (Variant::OBJECT, " multiplayer_peer" , PROPERTY_HINT_RESOURCE_TYPE, " MultiplayerPeer" , PROPERTY_USAGE_NONE), " set_multiplayer_peer" , " get_multiplayer_peer" );
646
725
ADD_PROPERTY (PropertyInfo (Variant::OBJECT, " root_node" , PROPERTY_HINT_RESOURCE_TYPE, " Node" , PROPERTY_USAGE_NONE), " set_root_node" , " get_root_node" );
647
726
ADD_PROPERTY_DEFAULT (" refuse_new_connections" , false );
648
- ADD_PROPERTY (PropertyInfo (Variant::OBJECT, " replicator" , PROPERTY_HINT_RESOURCE_TYPE, " MultiplayerReplicator" , PROPERTY_USAGE_NONE), " " , " get_replicator" );
649
727
650
728
ADD_SIGNAL (MethodInfo (" peer_connected" , PropertyInfo (Variant::INT, " id" )));
651
729
ADD_SIGNAL (MethodInfo (" peer_disconnected" , PropertyInfo (Variant::INT, " id" )));
@@ -656,13 +734,16 @@ void MultiplayerAPI::_bind_methods() {
656
734
}
657
735
658
736
MultiplayerAPI::MultiplayerAPI () {
659
- replicator = memnew (MultiplayerReplicator (this ));
737
+ if (create_default_replication_interface) {
738
+ replicator = Ref<MultiplayerReplicationInterface>(create_default_replication_interface (this ));
739
+ } else {
740
+ replicator.instantiate ();
741
+ }
660
742
rpc_manager = memnew (RPCManager (this ));
661
743
clear ();
662
744
}
663
745
664
746
MultiplayerAPI::~MultiplayerAPI () {
665
747
clear ();
666
- memdelete (replicator);
667
748
memdelete (rpc_manager);
668
749
}
0 commit comments