diff --git a/src/client/Perlin.cpp b/src/client/Perlin.cpp index a102a8b..db168ee 100644 --- a/src/client/Perlin.cpp +++ b/src/client/Perlin.cpp @@ -242,9 +242,6 @@ namespace perlin { else if (!friendLease && versionOverride.protocol > 0 && versionOverride.server == options.server) session->SetProtocolOverride(versionOverride.protocol, versionOverride.version); session->SetRecordTap(replayCtl.NewSessionTap()); - if (connectsInFlight.load() == 0) - std::erase_if(retiredSessions, - [](const std::unique_ptr& s) { return !s->Transferring(); }); session->SetPacketHandler([this](uint32_t id, const std::vector& body) { if (!modWantPackets.load() || body.size() > 65536) return; diff --git a/src/client/PerlinFrame.cpp b/src/client/PerlinFrame.cpp index 813b5f8..7427bee 100644 --- a/src/client/PerlinFrame.cpp +++ b/src/client/PerlinFrame.cpp @@ -384,6 +384,11 @@ namespace perlin { camera.aspect = static_cast(width) / static_cast(height); PumpReplay(dt); + // retired sessions die here, before this frame takes `live`: Connect() can run mid-frame (a Discord + // join, a transfer, a button) while the rest of the frame still holds the old session + if (connectsInFlight.load() == 0) + std::erase_if(retiredSessions, + [](const std::unique_ptr& s) { return !s->Transferring(); }); live = sessionReady && session && !session->Transferring() ? session.get() : nullptr; if (live) { const physics::State& viewerState = player.State(); diff --git a/src/client/PerlinReplay.cpp b/src/client/PerlinReplay.cpp index 3c56667..faf9f58 100644 --- a/src/client/PerlinReplay.cpp +++ b/src/client/PerlinReplay.cpp @@ -336,9 +336,6 @@ namespace perlin { : 1 << 20); session->SetPackDirectory(paths::DataDir() + "/server_packs"); sessionReady = true; - if (connectsInFlight.load() == 0) - std::erase_if(retiredSessions, - [](const std::unique_ptr& r) { return !r->Transferring(); }); } void Perlin::MountReplayPacks() {