Skip to content

Commit 2b263cb

Browse files
committed
Fixes bug about the client not properly storing its own latency info.
1 parent c39ab38 commit 2b263cb

7 files changed

Lines changed: 279 additions & 200 deletions

godot4/gd_scene_synchronizer.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ void GdSceneSynchronizer::_bind_methods() {
6262
ClassDB::bind_method(D_METHOD("set_nodes_relevancy_update_time", "time"), &GdSceneSynchronizer::set_nodes_relevancy_update_time);
6363
ClassDB::bind_method(D_METHOD("get_nodes_relevancy_update_time"), &GdSceneSynchronizer::get_nodes_relevancy_update_time);
6464

65+
ClassDB::bind_method(D_METHOD("set_frames_per_seconds", "fps"), &GdSceneSynchronizer::set_frames_per_seconds);
66+
ClassDB::bind_method(D_METHOD("get_frames_per_seconds"), &GdSceneSynchronizer::get_frames_per_seconds);
67+
6568
ClassDB::bind_method(D_METHOD("register_node", "node"), &GdSceneSynchronizer::register_node_gdscript);
6669
ClassDB::bind_method(D_METHOD("register_node_as_controller_by_peer", "node", "peer"), &GdSceneSynchronizer::register_node_as_controller_by_peer);
6770
ClassDB::bind_method(D_METHOD("unregister_node", "node"), &GdSceneSynchronizer::unregister_node);
@@ -84,6 +87,8 @@ void GdSceneSynchronizer::_bind_methods() {
8487

8588
ClassDB::bind_method(D_METHOD("setup_trickled_sync", "node", "collect_epoch_func", "apply_epoch_func"), &GdSceneSynchronizer::setup_trickled_sync);
8689

90+
ClassDB::bind_method(D_METHOD("get_peer_latency", "peer"), &GdSceneSynchronizer::get_peer_latency);
91+
8792
ClassDB::bind_method(D_METHOD("sync_group_create"), &GdSceneSynchronizer::sync_group_create);
8893
ClassDB::bind_method(D_METHOD("sync_group_add_node", "node_id", "group_id", "realtime"), &GdSceneSynchronizer::sync_group_add_node_by_id);
8994
ClassDB::bind_method(D_METHOD("sync_group_remove_node", "node_id", "group_id"), &GdSceneSynchronizer::sync_group_remove_node_by_id);
@@ -101,7 +106,7 @@ void GdSceneSynchronizer::_bind_methods() {
101106

102107
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &GdSceneSynchronizer::set_enabled);
103108
ClassDB::bind_method(D_METHOD("set_peer_networking_enable", "peer", "enabled"), &GdSceneSynchronizer::set_peer_networking_enable);
104-
ClassDB::bind_method(D_METHOD("get_peer_networking_enable", "peer"), &GdSceneSynchronizer::is_peer_networking_enable);
109+
ClassDB::bind_method(D_METHOD("get_peer_networking_enabled", "peer"), &GdSceneSynchronizer::is_peer_networking_enabled);
105110

106111
ClassDB::bind_method(D_METHOD("is_server"), &GdSceneSynchronizer::is_server);
107112
ClassDB::bind_method(D_METHOD("is_client"), &GdSceneSynchronizer::is_client);
@@ -428,6 +433,14 @@ real_t GdSceneSynchronizer::get_nodes_relevancy_update_time() const {
428433
return scene_synchronizer.get_objects_relevancy_update_time();
429434
}
430435

436+
void GdSceneSynchronizer::set_frames_per_seconds(int p_fps) {
437+
scene_synchronizer.set_frames_per_seconds(p_fps);
438+
}
439+
440+
int GdSceneSynchronizer::get_frames_per_seconds() const {
441+
return scene_synchronizer.get_frames_per_seconds();
442+
}
443+
431444
void GdSceneSynchronizer::_rpc_net_sync_reliable(const Vector<uint8_t> &p_args) {
432445
static_cast<GdNetworkInterface *>(&scene_synchronizer.get_network_interface())->gd_rpc_receive(p_args);
433446
}
@@ -586,6 +599,10 @@ void GdSceneSynchronizer::setup_trickled_sync(Node *p_node, const Callable &p_co
586599
});
587600
}
588601

602+
int GdSceneSynchronizer::get_peer_latency(int p_peer) const {
603+
return scene_synchronizer.get_peer_latency(p_peer);
604+
}
605+
589606
Array GdSceneSynchronizer::local_controller_get_controlled_nodes() const {
590607
Array a;
591608

@@ -700,8 +717,8 @@ void GdSceneSynchronizer::set_peer_networking_enable(int p_peer, bool p_enable)
700717
scene_synchronizer.set_peer_networking_enable(p_peer, p_enable);
701718
}
702719

703-
bool GdSceneSynchronizer::is_peer_networking_enable(int p_peer) const {
704-
return scene_synchronizer.is_peer_networking_enable(p_peer);
720+
bool GdSceneSynchronizer::is_peer_networking_enabled(int p_peer) const {
721+
return scene_synchronizer.is_peer_networking_enabled(p_peer);
705722
}
706723

707724
bool GdSceneSynchronizer::is_server() const {

godot4/gd_scene_synchronizer.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ class GdSceneSynchronizer : public Node, public NS::SynchronizerManager {
6262
void set_nodes_relevancy_update_time(real_t p_time);
6363
real_t get_nodes_relevancy_update_time() const;
6464

65+
void set_frames_per_seconds(int p_fps);
66+
int get_frames_per_seconds() const;
67+
6568
public: // ---------------------------------------- Scene Synchronizer Interface
6669
virtual void on_init_synchronizer(bool p_was_generating_ids) override;
6770
virtual void on_uninit_synchronizer() override;
@@ -139,6 +142,8 @@ class GdSceneSynchronizer : public Node, public NS::SynchronizerManager {
139142

140143
Array local_controller_get_controlled_nodes() const;
141144

145+
int get_peer_latency(int p_peer) const;
146+
142147
/// Creates a realtime sync group containing a list of nodes.
143148
/// The Peers listening to this group will receive the updates only
144149
/// from the nodes within this group.
@@ -177,7 +182,7 @@ class GdSceneSynchronizer : public Node, public NS::SynchronizerManager {
177182
void set_enabled(bool p_enable);
178183

179184
void set_peer_networking_enable(int p_peer, bool p_enable);
180-
bool is_peer_networking_enable(int p_peer) const;
185+
bool is_peer_networking_enabled(int p_peer) const;
181186

182187
/// Returns true if this peer is server.
183188
bool is_server() const;

net_utilities.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
#include "networked_controller.h"
55
#include <limits>
66

7-
void NS::PeerData::set_ping(int p_ping) {
8-
compressed_ping = std::round(float(std::min(p_ping, 1000)) / 4.0);
7+
void NS::PeerData::set_latency(int p_latency) {
8+
compressed_latency = std::round(float(std::min(p_latency, 1000)) / 4.0);
99
}
1010

11-
int NS::PeerData::get_ping() const {
12-
return compressed_ping * 4.0;
11+
int NS::PeerData::get_latency() const {
12+
return compressed_latency * 4.0;
1313
}
1414

1515
bool NS::SyncGroup::is_realtime_node_list_changed() const {
@@ -20,8 +20,8 @@ bool NS::SyncGroup::is_trickled_node_list_changed() const {
2020
return trickled_sync_objects_list_changed;
2121
}
2222

23-
const std::vector<int> NS::SyncGroup::get_peers_with_newly_calculated_ping() const {
24-
return peers_with_newly_calculated_ping;
23+
const std::vector<int> NS::SyncGroup::get_peers_with_newly_calculated_latency() const {
24+
return peers_with_newly_calculated_latency;
2525
}
2626

2727
const LocalVector<NS::SyncGroup::SimulatedObjectInfo> &NS::SyncGroup::get_simulated_sync_objects() const {
@@ -47,7 +47,7 @@ void NS::SyncGroup::mark_changes_as_notified() {
4747
}
4848
simulated_sync_objects_list_changed = false;
4949
trickled_sync_objects_list_changed = false;
50-
peers_with_newly_calculated_ping.clear();
50+
peers_with_newly_calculated_latency.clear();
5151
}
5252

5353
void NS::SyncGroup::add_listening_peer(int p_peer) {
@@ -66,7 +66,7 @@ uint32_t NS::SyncGroup::add_new_sync_object(ObjectData *p_object_data, bool p_is
6666
// Regardless if it's simulated or not.
6767
const int peer = p_object_data->get_controller()->server_get_associated_peer();
6868
if (NS::VecFunc::insert_unique(networked_peers, peer)) {
69-
NS::VecFunc::insert_unique(peers_with_newly_calculated_ping, peer);
69+
NS::VecFunc::insert_unique(peers_with_newly_calculated_latency, peer);
7070
}
7171
}
7272

@@ -138,7 +138,7 @@ void NS::SyncGroup::remove_sync_object(std::size_t p_index, bool p_is_simulated)
138138

139139
if (associted_peer != 0) {
140140
NS::VecFunc::remove_unordered(networked_peers, associted_peer);
141-
NS::VecFunc::remove_unordered(peers_with_newly_calculated_ping, associted_peer);
141+
NS::VecFunc::remove_unordered(peers_with_newly_calculated_latency, associted_peer);
142142
}
143143
}
144144

@@ -266,9 +266,9 @@ void NS::SyncGroup::sort_trickled_node_by_update_priority() {
266266
trickled_sync_objects.sort_custom<DNIComparator>();
267267
}
268268

269-
void NS::SyncGroup::notify_peer_has_newly_calculated_ping(int p_peer) {
269+
void NS::SyncGroup::notify_peer_has_newly_calculated_latency(int p_peer) {
270270
if (NS::VecFunc::has(networked_peers, p_peer)) {
271-
NS::VecFunc::insert_unique(peers_with_newly_calculated_ping, p_peer);
271+
NS::VecFunc::insert_unique(peers_with_newly_calculated_latency, p_peer);
272272
}
273273
}
274274

net_utilities.h

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -426,28 +426,45 @@ void StatisticalRingBuffer<T>::force_recompute_avg_sum() {
426426
}
427427
}
428428

429-
struct PeerData {
430-
ObjectNetId controller_id = ObjectNetId::NONE;
431-
// For new peers notify the state as soon as possible.
432-
bool force_notify_snapshot = true;
433-
// For new peers a full snapshot is needed.
434-
bool need_full_snapshot = true;
429+
// These data are used by the server and are never synchronized.
430+
struct PeerAuthorityData {
435431
// Used to know if the peer is enabled.
436432
bool enabled = true;
433+
437434
// The Sync group this peer is in.
438435
SyncGroupId sync_group_id = SyncGroupId::GLOBAL;
436+
};
439437

440-
// The ping between this peer and the server in ms.
441-
std::chrono::high_resolution_clock::time_point ping_timestamp;
442-
bool ping_calculation_in_progress = false;
438+
struct PeerData {
439+
public:
440+
PeerAuthorityData authority_data;
443441

444-
void set_ping(int p_ping);
445-
int get_ping() const;
446-
void set_compressed_ping(std::uint8_t p_compressed_ping) { compressed_ping = p_compressed_ping; }
447-
std::uint8_t get_compressed_ping() const { return compressed_ping; }
442+
ObjectNetId controller_id = ObjectNetId::NONE;
448443

449444
private:
450-
std::uint8_t compressed_ping = 0;
445+
std::uint8_t compressed_latency = -1;
446+
447+
public:
448+
// In ms
449+
void set_latency(int p_ping);
450+
451+
// In ms
452+
int get_latency() const;
453+
454+
void set_compressed_latency(std::uint8_t p_compressed_latency) { compressed_latency = p_compressed_latency; }
455+
std::uint8_t get_compressed_latency() const { return compressed_latency; }
456+
};
457+
458+
struct PeerServerData {
459+
// For new peers notify the state as soon as possible.
460+
bool force_notify_snapshot = true;
461+
462+
// For new peers a full snapshot is needed.
463+
bool need_full_snapshot = true;
464+
465+
// The latency, in ms, between this peer and the server.
466+
std::chrono::high_resolution_clock::time_point latency_ping_timestamp;
467+
bool latency_calculation_in_progress = false;
451468
};
452469

453470
struct SyncGroup {
@@ -509,7 +526,7 @@ struct SyncGroup {
509526
LocalVector<TrickledObjectInfo> trickled_sync_objects;
510527

511528
std::vector<int> networked_peers;
512-
std::vector<int> peers_with_newly_calculated_ping;
529+
std::vector<int> peers_with_newly_calculated_latency;
513530

514531
std::vector<int> listening_peers;
515532

@@ -521,7 +538,7 @@ struct SyncGroup {
521538
public:
522539
bool is_realtime_node_list_changed() const;
523540
bool is_trickled_node_list_changed() const;
524-
const std::vector<int> get_peers_with_newly_calculated_ping() const;
541+
const std::vector<int> get_peers_with_newly_calculated_latency() const;
525542

526543
const LocalVector<NS::SyncGroup::SimulatedObjectInfo> &get_simulated_sync_objects() const;
527544
const LocalVector<NS::SyncGroup::TrickledObjectInfo> &get_trickled_sync_objects() const;
@@ -548,7 +565,7 @@ struct SyncGroup {
548565

549566
void sort_trickled_node_by_update_priority();
550567

551-
void notify_peer_has_newly_calculated_ping(int p_peer);
568+
void notify_peer_has_newly_calculated_latency(int p_peer);
552569

553570
private:
554571
void notify_controller_about_simulating_peers(struct ObjectData *p_object_data, bool p_simulating);

0 commit comments

Comments
 (0)