diff --git a/Source/Core/Core/HW/EXI_DeviceSlippi.cpp b/Source/Core/Core/HW/EXI_DeviceSlippi.cpp index 9459ac4abd..95a051f26c 100644 --- a/Source/Core/Core/HW/EXI_DeviceSlippi.cpp +++ b/Source/Core/Core/HW/EXI_DeviceSlippi.cpp @@ -1486,6 +1486,11 @@ bool CEXISlippi::shouldSkipOnlineFrame(s32 frame, s32 finalizedFrame) bool CEXISlippi::shouldAdvanceOnlineFrame(s32 frame) { + // If the opponent is a bot running ahead to give us more inputs, we should + // just keep going at our own pace rather than trying to catch up. + if (opponentRunahead()) + return false; + // Logic below is used to test frame advance by forcing it more often // SConfig::GetInstance().m_EmulationSpeed = 0.5f; // if (frame > 120 && frame % 10 < 3) @@ -1610,6 +1615,24 @@ void CEXISlippi::handleSendInputs(s32 frame, u8 delay, s32 checksumFrame, u32 ch slippi_netplay->SendSlippiPad(std::move(pad)); } +bool CEXISlippi::opponentRunahead() +{ + // Bot players might be running ahead to "donate" their delay frames to us. + + // Only registered bot accounts are allowed to do this. + auto player_info = matchmaking->GetPlayerInfo(); + for (int i = 0; i < player_info.size(); i++) + { + if (i == matchmaking->LocalPlayerIndex()) + continue; + + if (!player_info[i].is_bot) + return false; + } + + return true; +} + void CEXISlippi::prepareOpponentInputs(s32 frame, bool shouldSkip) { m_read_queue.clear(); diff --git a/Source/Core/Core/HW/EXI_DeviceSlippi.h b/Source/Core/Core/HW/EXI_DeviceSlippi.h index 1b581da0e8..be6785f97f 100644 --- a/Source/Core/Core/HW/EXI_DeviceSlippi.h +++ b/Source/Core/Core/HW/EXI_DeviceSlippi.h @@ -210,6 +210,7 @@ class CEXISlippi : public IEXIDevice void setMatchSelections(u8 *payload); bool shouldSkipOnlineFrame(s32 frame, s32 finalizedFrame); bool shouldAdvanceOnlineFrame(s32 frame); + bool opponentRunahead(); void handleLogInRequest(); void handleLogOutRequest(); void handleUpdateAppRequest();