[ntcore] Add method to get server time offset (#4847)

Also exposes this as an event signaled when the offset is updated due to
a ping response from the server.
This commit is contained in:
Peter Johnson
2022-12-30 20:15:57 -08:00
committed by GitHub
parent fe1b62647f
commit f1151d375f
29 changed files with 718 additions and 60 deletions

View File

@@ -110,6 +110,9 @@ void InstanceImpl::StartServer(std::string_view persistFilename,
networkMode &= ~NT_NET_MODE_STARTING;
});
networkMode = NT_NET_MODE_SERVER | NT_NET_MODE_STARTING;
listenerStorage.NotifyTimeSync({}, NT_EVENT_TIMESYNC, 0, 0, true);
m_serverTimeOffset = 0;
m_rtt2 = 0;
}
void InstanceImpl::StopServer() {
@@ -121,6 +124,9 @@ void InstanceImpl::StopServer() {
}
server = std::move(m_networkServer);
networkMode = NT_NET_MODE_NONE;
listenerStorage.NotifyTimeSync({}, NT_EVENT_TIMESYNC, 0, 0, false);
m_serverTimeOffset.reset();
m_rtt2 = 0;
}
}
@@ -143,7 +149,19 @@ void InstanceImpl::StartClient4(std::string_view identity) {
return;
}
m_networkClient = std::make_shared<NetworkClient>(
m_inst, identity, localStorage, connectionList, logger);
m_inst, identity, localStorage, connectionList, logger,
[this](int64_t serverTimeOffset, int64_t rtt2, bool valid) {
std::scoped_lock lock{m_mutex};
listenerStorage.NotifyTimeSync({}, NT_EVENT_TIMESYNC, serverTimeOffset,
rtt2, valid);
if (valid) {
m_serverTimeOffset = serverTimeOffset;
m_rtt2 = rtt2;
} else {
m_serverTimeOffset.reset();
m_rtt2 = 0;
}
});
if (!m_servers.empty()) {
m_networkClient->SetServers(m_servers);
}
@@ -151,12 +169,22 @@ void InstanceImpl::StartClient4(std::string_view identity) {
}
void InstanceImpl::StopClient() {
std::scoped_lock lock{m_mutex};
if ((networkMode & (NT_NET_MODE_CLIENT3 | NT_NET_MODE_CLIENT4)) == 0) {
return;
std::shared_ptr<INetworkClient> client;
{
std::scoped_lock lock{m_mutex};
if ((networkMode & (NT_NET_MODE_CLIENT3 | NT_NET_MODE_CLIENT4)) == 0) {
return;
}
client = std::move(m_networkClient);
networkMode = NT_NET_MODE_NONE;
}
client.reset();
{
std::scoped_lock lock{m_mutex};
listenerStorage.NotifyTimeSync({}, NT_EVENT_TIMESYNC, 0, 0, false);
m_serverTimeOffset.reset();
m_rtt2 = 0;
}
m_networkClient.reset();
networkMode = NT_NET_MODE_NONE;
}
void InstanceImpl::SetServers(
@@ -178,12 +206,33 @@ std::shared_ptr<INetworkClient> InstanceImpl::GetClient() {
return m_networkClient;
}
std::optional<int64_t> InstanceImpl::GetServerTimeOffset() {
std::scoped_lock lock{m_mutex};
return m_serverTimeOffset;
}
void InstanceImpl::AddTimeSyncListener(NT_Listener listener,
unsigned int eventMask) {
std::scoped_lock lock{m_mutex};
eventMask &= (NT_EVENT_TIMESYNC | NT_EVENT_IMMEDIATE);
listenerStorage.Activate(listener, eventMask);
if ((eventMask & (NT_EVENT_TIMESYNC | NT_EVENT_IMMEDIATE)) ==
(NT_EVENT_TIMESYNC | NT_EVENT_IMMEDIATE) &&
m_serverTimeOffset) {
listenerStorage.NotifyTimeSync({&listener, 1},
NT_EVENT_TIMESYNC | NT_EVENT_IMMEDIATE,
*m_serverTimeOffset, m_rtt2, true);
}
}
void InstanceImpl::Reset() {
std::scoped_lock lock{m_mutex};
m_networkServer.reset();
m_networkClient.reset();
m_servers.clear();
networkMode = NT_NET_MODE_NONE;
m_serverTimeOffset.reset();
m_rtt2 = 0;
listenerStorage.Reset();
// connectionList should have been cleared by destroying networkClient/server