possible desync fixes

This commit is contained in:
Nikhil Narayana 2022-05-30 12:33:51 -07:00
commit 76f0895d98
2 changed files with 23 additions and 39 deletions

View file

@ -1662,7 +1662,7 @@ bool CEXISlippi::shouldSkipOnlineFrame(s32 frame, s32 finalizedFrame)
isCurrentlySkipping = true; isCurrentlySkipping = true;
int maxSkipFrames = frame <= 120 ? 5 : 1; // On early frames, support skipping more frames int maxSkipFrames = frame <= 120 ? 5 : 1; // On early frames, support skipping more frames
framesToSkip = ((offsetUs - 10000) / 16683) + 1; framesToSkip = ((offsetUs - t1) / frameTime) + 1;
framesToSkip = framesToSkip =
framesToSkip > maxSkipFrames ? maxSkipFrames : framesToSkip; // Only skip 5 frames max framesToSkip > maxSkipFrames ? maxSkipFrames : framesToSkip; // Only skip 5 frames max
@ -1732,9 +1732,7 @@ bool CEXISlippi::shouldAdvanceOnlineFrame(s32 frame)
deviation = frameWindowMultiplier * -maxSlowDownAmount; deviation = frameWindowMultiplier * -maxSlowDownAmount;
} }
// If we are behind (negative offset) we want to go above 100% run speed, so we need to subtract auto dynamicEmulationSpeed = 1.0f + deviation;
// the deviation value
auto dynamicEmulationSpeed = 1.0f - deviation;
SConfig::GetInstance().m_EmulationSpeed = dynamicEmulationSpeed; SConfig::GetInstance().m_EmulationSpeed = dynamicEmulationSpeed;
// SConfig::GetInstance().m_EmulationSpeed = 0.97f; // used for testing // SConfig::GetInstance().m_EmulationSpeed = 0.97f; // used for testing
@ -1867,6 +1865,7 @@ void CEXISlippi::prepareOpponentInputs(s32 frame, bool shouldSkip)
int32_t latestFrame = results[i]->latestFrame; int32_t latestFrame = results[i]->latestFrame;
if (latestFrame > frame) if (latestFrame > frame)
latestFrame = frame; latestFrame = frame;
latestFrameRead[i] = latestFrame;
appendWordToBuffer(&m_read_queue, static_cast<u32>(latestFrame)); appendWordToBuffer(&m_read_queue, static_cast<u32>(latestFrame));
// INFO_LOG(SLIPPI_ONLINE, "Sending frame num %d for pIdx %d (offset: %d)", latestFrame, i, // INFO_LOG(SLIPPI_ONLINE, "Sending frame num %d for pIdx %d (offset: %d)", latestFrame, i,
// offset[i]); // offset[i]);
@ -1874,6 +1873,7 @@ void CEXISlippi::prepareOpponentInputs(s32 frame, bool shouldSkip)
// Send the current frame for any unused player slots. // Send the current frame for any unused player slots.
for (int i = remotePlayerCount; i < SLIPPI_REMOTE_PLAYER_MAX; i++) for (int i = remotePlayerCount; i < SLIPPI_REMOTE_PLAYER_MAX; i++)
{ {
latestFrameRead[i] = frame;
appendWordToBuffer(&m_read_queue, static_cast<u32>(frame)); appendWordToBuffer(&m_read_queue, static_cast<u32>(frame));
} }
@ -1898,8 +1898,6 @@ void CEXISlippi::prepareOpponentInputs(s32 frame, bool shouldSkip)
m_read_queue.insert(m_read_queue.end(), tx.begin(), tx.end()); m_read_queue.insert(m_read_queue.end(), tx.begin(), tx.end());
} }
slippi_netplay->DropOldRemoteInputs(frame);
// ERROR_LOG(SLIPPI_ONLINE, "EXI: [%d] %X %X %X %X %X %X %X %X", latestFrame, m_read_queue[5], // ERROR_LOG(SLIPPI_ONLINE, "EXI: [%d] %X %X %X %X %X %X %X %X", latestFrame, m_read_queue[5],
// m_read_queue[6], m_read_queue[7], m_read_queue[8], m_read_queue[9], m_read_queue[10], // m_read_queue[6], m_read_queue[7], m_read_queue[8], m_read_queue[9], m_read_queue[10],
// m_read_queue[11], m_read_queue[12]); // m_read_queue[11], m_read_queue[12]);

View file

@ -281,32 +281,37 @@ unsigned int SlippiNetplayClient::OnData(sf::Packet& packet, ENetPeer* peer)
auto packetData = (u8*)packet.getData(); auto packetData = (u8*)packet.getData();
INFO_LOG_FMT(SLIPPI_ONLINE, "Receiving a packet of inputs [{}]...", frame); // INFO_LOG_FMT(SLIPPI_ONLINE, "Receiving a packet of inputs [{}]...", frame);
INFO_LOG_FMT(SLIPPI_ONLINE, "Receiving a packet of inputs from player {}({}) [{}]...", // INFO_LOG_FMT(SLIPPI_ONLINE, "Receiving a packet of inputs from player {}({}) [{}]...",
packetPlayerPort, pIdx, frame); // packetPlayerPort, pIdx, frame);
int32_t headFrame = remotePadQueue[pIdx].empty() ? 0 : remotePadQueue[pIdx].front()->frame; s64 frame64 = static_cast<s64>(frame);
int inputsToCopy = frame - headFrame; s32 headFrame = remotePadQueue[pIdx].empty() ? 0 : remotePadQueue[pIdx].front()->frame;
s64 inputsToCopy = frame64 - static_cast<s64>(headFrame);
// Not sure what the max is here. If we never ack frames it could get big... // Check that the packet actually contains the data it claims to
if (inputsToCopy > 128) if ((6 + inputsToCopy * SLIPPI_PAD_DATA_SIZE) > static_cast<s64>(packet.getDataSize()))
{ {
ERROR_LOG_FMT( ERROR_LOG_FMT(
SLIPPI_ONLINE, SLIPPI_ONLINE,
"Netplay packet too small to read pad buffer. Size: {}, Inputs: {}, MinSize: {}", "Netplay packet too small to read pad buffer. Size: {}, Inputs: {}, MinSize: {}",
(int)packet.getDataSize(), inputsToCopy, 5 + inputsToCopy * SLIPPI_PAD_DATA_SIZE); static_cast<int>(packet.getDataSize()), inputsToCopy,
6 + inputsToCopy * SLIPPI_PAD_DATA_SIZE);
break; break;
} }
for (int i = inputsToCopy - 1; i >= 0; i--) // Not sure what the max is here. If we never ack frames it could get big...
if (inputsToCopy > 128)
{ {
auto pad = ERROR_LOG_FMT(SLIPPI_ONLINE, "Netplay packet contained too many frames: {}", inputsToCopy);
std::make_unique<SlippiPad>(frame - i, pIdx, &packetData[6 + i * SLIPPI_PAD_DATA_SIZE]); break;
INFO_LOG(SLIPPI_ONLINE, "Rcv [%d] -> %02X %02X %02X %02X %02X %02X %02X %02X", pad->frame, }
pad->padBuf[0], pad->padBuf[1], pad->padBuf[2], pad->padBuf[3], pad->padBuf[4],
pad->padBuf[5], pad->padBuf[6], pad->padBuf[7]);
for (s64 i = inputsToCopy - 1; i >= 0; i--)
{
auto pad = std::make_unique<SlippiPad>(static_cast<s32>(frame64 - i), pIdx,
&packetData[6 + i * SLIPPI_PAD_DATA_SIZE]);
remotePadQueue[pIdx].push_front(std::move(pad)); remotePadQueue[pIdx].push_front(std::move(pad));
} }
} }
@ -1199,28 +1204,9 @@ void SlippiNetplayClient::DropOldRemoteInputs(int32_t finalizedFrame)
{ {
std::lock_guard<std::mutex> lk(pad_mutex); std::lock_guard<std::mutex> lk(pad_mutex);
// Remove pad reports that should no longer be needed, compute the lowest frame recieved by
// all remote players that can be safely dropped.
int lowestCommonFrame = 0;
for (int i = 0; i < m_remotePlayerCount; i++) for (int i = 0; i < m_remotePlayerCount; i++)
{ {
int playerFrame = 0;
for (auto it = remotePadQueue[i].begin(); it != remotePadQueue[i].end(); ++it)
{
if (it->get()->frame > playerFrame)
playerFrame = it->get()->frame;
}
if (lowestCommonFrame == 0 || playerFrame < lowestCommonFrame)
lowestCommonFrame = playerFrame;
}
for (int i = 0; i < m_remotePlayerCount; i++)
{
// INFO_LOG_FMT(SLIPPI_ONLINE, "remotePadQueue[{}] size: {}", i, remotePadQueue[i].size());
while (remotePadQueue[i].size() > 1 && remotePadQueue[i].back()->frame < finalizedFrame) while (remotePadQueue[i].size() > 1 && remotePadQueue[i].back()->frame < finalizedFrame)
/*INFO_LOG_FMT(SLIPPI_ONLINE, "Popping inputs for frame {} from back of player {} queue",
remotePadQueue[i].back()->frame, i);*/
remotePadQueue[i].pop_back(); remotePadQueue[i].pop_back();
} }
} }