From 6c896c2ef79c1740d7dea6fae95518c768de8931 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 4 Apr 2024 14:35:36 +1100 Subject: [PATCH] Make ping updates more accurate --- source/game/StarNetPackets.cpp | 33 +++++++++++++++++++++++----- source/game/StarNetPackets.hpp | 10 +++++++++ source/game/StarUniverseClient.cpp | 1 + source/game/StarWorldClient.cpp | 13 ++++++++--- source/game/StarWorldClient.hpp | 1 + source/game/StarWorldClientState.cpp | 10 +++++++++ source/game/StarWorldClientState.hpp | 6 +++++ source/game/StarWorldServer.cpp | 2 +- 8 files changed, 66 insertions(+), 10 deletions(-) diff --git a/source/game/StarNetPackets.cpp b/source/game/StarNetPackets.cpp index fd127a2..3cbb3ad 100644 --- a/source/game/StarNetPackets.cpp +++ b/source/game/StarNetPackets.cpp @@ -924,15 +924,26 @@ void WorldStartAcknowledgePacket::write(DataStream& ds) const { } PingPacket::PingPacket() {} +PingPacket::PingPacket(int64_t time) : time(time) {} -void PingPacket::read(DataStream& ds) { +void PingPacket::readLegacy(DataStream& ds) { // Packets can't be empty, read the trash data ds.read(); + time = 0; +} + +void PingPacket::read(DataStream& ds) { + ds.readVlqI(time); +} + + +void PingPacket::writeLegacy(DataStream& ds) const { + // Packets can't be empty, write some trash data + ds.write(false); } void PingPacket::write(DataStream& ds) const { - // Packets can't be empty, write some trash data - ds.write(false); + ds.writeVlqI(time); } EntityCreatePacket::EntityCreatePacket(EntityType entityType, ByteArray storeData, ByteArray firstNetState, EntityId entityId) @@ -1234,15 +1245,25 @@ void FindUniqueEntityResponsePacket::write(DataStream& ds) const { } PongPacket::PongPacket() {} +PongPacket::PongPacket(int64_t time) : time(time) {} -void PongPacket::read(DataStream& ds) { +void PongPacket::readLegacy(DataStream& ds) { // Packets can't be empty, read the trash data ds.read(); + time = 0; +} + +void PongPacket::read(DataStream& ds) { + ds.readVlqI(time); +} + +void PongPacket::writeLegacy(DataStream& ds) const { + // Packets can't be empty, write some trash data + ds.write(false); } void PongPacket::write(DataStream& ds) const { - // Packets can't be empty, write some trash data - ds.write(false); + ds.writeVlqI(time); } StepUpdatePacket::StepUpdatePacket() : remoteTime(0.0) {} diff --git a/source/game/StarNetPackets.hpp b/source/game/StarNetPackets.hpp index 71ab09f..475f57a 100644 --- a/source/game/StarNetPackets.hpp +++ b/source/game/StarNetPackets.hpp @@ -603,9 +603,14 @@ struct FindUniqueEntityResponsePacket : PacketBase { PongPacket(); + PongPacket(int64_t time); + void readLegacy(DataStream& ds) override; void read(DataStream& ds) override; + void writeLegacy(DataStream& ds) const override; void write(DataStream& ds) const override; + + int64_t time = 0; }; struct ModifyTileListPacket : PacketBase { @@ -717,9 +722,14 @@ struct WorldStartAcknowledgePacket : PacketBase { PingPacket(); + PingPacket(int64_t time); + void readLegacy(DataStream& ds) override; void read(DataStream& ds) override; + void writeLegacy(DataStream& ds) const override; void write(DataStream& ds) const override; + + int64_t time = 0; }; struct EntityCreatePacket : PacketBase { diff --git a/source/game/StarUniverseClient.cpp b/source/game/StarUniverseClient.cpp index 752d081..adc6bef 100644 --- a/source/game/StarUniverseClient.cpp +++ b/source/game/StarUniverseClient.cpp @@ -123,6 +123,7 @@ Maybe UniverseClient::connect(UniverseConnection connection, bool allowA m_mainPlayer->setClientContext(m_clientContext); m_mainPlayer->setStatistics(m_statistics); m_worldClient = make_shared(m_mainPlayer); + m_worldClient->clientState().setLegacy(m_legacyServer); m_worldClient->setAsyncLighting(true); for (auto& pair : m_luaCallbacks) m_worldClient->setLuaCallbacks(pair.first, pair.second); diff --git a/source/game/StarWorldClient.cpp b/source/game/StarWorldClient.cpp index b1ad698..3b8f1a3 100644 --- a/source/game/StarWorldClient.cpp +++ b/source/game/StarWorldClient.cpp @@ -403,6 +403,10 @@ RectI WorldClient::clientWindow() const { return m_clientState.window(); } +WorldClientState& WorldClient::clientState() { + return m_clientState; +} + void WorldClient::render(WorldRenderData& renderData, unsigned bufferTiles) { if (!m_lightingThread && m_asyncLighting) m_lightingThread = Thread::invoke("WorldClient::lightingMain", mem_fn(&WorldClient::lightingMain), this); @@ -1038,7 +1042,9 @@ void WorldClient::handleIncomingPackets(List const& packets) { m_worldTemplate->setWorldParameters(netLoadVisitableWorldParameters(worldParametersUpdate->parametersData)); } else if (auto pongPacket = as(packet)) { - if (m_pingTime) + if (pongPacket->time) + m_latency = Time::monotonicMilliseconds() - pongPacket->time; + else if (m_pingTime) m_latency = Time::monotonicMilliseconds() - m_pingTime.take(); } else { @@ -1203,10 +1209,11 @@ void WorldClient::update(float dt) { queueUpdatePackets(m_entityUpdateTimer.wrapTick(dt)); - if (m_pingTime.isNothing()) { + if ((!m_clientState.legacy() && m_currentStep % 3 == 0) || m_pingTime.isNothing()) { m_pingTime = Time::monotonicMilliseconds(); - m_outgoingPackets.append(make_shared()); + m_outgoingPackets.append(make_shared(*m_pingTime)); } + LogMap::set("client_ping", m_latency); // Remove active sectors that are outside of the current monitoring region diff --git a/source/game/StarWorldClient.hpp b/source/game/StarWorldClient.hpp index 6f40b63..e00a3b8 100644 --- a/source/game/StarWorldClient.hpp +++ b/source/game/StarWorldClient.hpp @@ -143,6 +143,7 @@ public: void centerClientWindowOnPlayer(Vec2U const& windowSize); void centerClientWindowOnPlayer(); RectI clientWindow() const; + WorldClientState& clientState(); void update(float dt); // borderTiles here should extend the client window for border tile diff --git a/source/game/StarWorldClientState.cpp b/source/game/StarWorldClientState.cpp index 5dc6b12..21552cd 100644 --- a/source/game/StarWorldClientState.cpp +++ b/source/game/StarWorldClientState.cpp @@ -22,6 +22,8 @@ WorldClientState::WorldClientState() { m_netGroup.addNetElement(&m_playerId); m_netGroup.addNetElement(&m_clientPresenceEntities); + + m_legacy = false; } RectI WorldClientState::window() const { @@ -87,6 +89,14 @@ void WorldClientState::readDelta(ByteArray delta) { m_netGroup.readNetState(std::move(delta)); } +void WorldClientState::setLegacy(bool legacy) { + m_legacy = legacy; +} + +bool WorldClientState::legacy() const { + return m_legacy; +} + void WorldClientState::reset() { m_netVersion = 0; } diff --git a/source/game/StarWorldClientState.hpp b/source/game/StarWorldClientState.hpp index 31ff52f..920fef4 100644 --- a/source/game/StarWorldClientState.hpp +++ b/source/game/StarWorldClientState.hpp @@ -36,6 +36,10 @@ public: ByteArray writeDelta(); void readDelta(ByteArray delta); + // Whether the client is connected to a legacy server. + void setLegacy(bool legacy); + bool legacy() const; + void reset(); private: @@ -52,6 +56,8 @@ private: NetElementInt m_playerId; NetElementData> m_clientPresenceEntities; + + bool m_legacy; }; } diff --git a/source/game/StarWorldServer.cpp b/source/game/StarWorldServer.cpp index ec144da..1b4041f 100644 --- a/source/game/StarWorldServer.cpp +++ b/source/game/StarWorldServer.cpp @@ -520,7 +520,7 @@ void WorldServer::handleIncomingPackets(ConnectionId clientId, List c response.get>().fail(entityMessageResponsePacket->response.left()); } } else if (auto pingPacket = as(packet)) { - clientInfo->outgoingPackets.append(make_shared()); + clientInfo->outgoingPackets.append(make_shared(pingPacket->time)); } else if (auto updateWorldProperties = as(packet)) { // Kae: Properties set to null (nil from Lua) should be erased instead of lingering around