Multiplayer end time synchronization
Currently, when a multiplayer run is completed, every player's end time differs. What can be implemented is showing the same end time for all players. It can be done by getting the SecondsPartial of every player, comparing each to see which is the lowest, and then either:
- Change the SecondsPartial of every other player to match that of the player who hit button 31 first. OR
- Change the time display of every other player to match that of the player who hit button 31 first.
In general, we can calculate the end time of the player hitting the button and send that time to all other players together with the last button press.
The implementation on how to set the correct time for all other players depends on when the time is displayed on the screen:
- Modify the end time: If the shown time is calculated and shown after
endSecondsandendPartialSecondsin the LevelState have been set, we can use that time to modify theendSecondsandendPartialSecondsin relation to the start time. - Modify the start time: Before spawning the pawn pressing the last button, we get the current time just like Refunct does and modify the
startSecondsandstartPartialSecondsto produce the correct result when Refunct gets the current time and calculates the time diff. This depends on https://github.com/oberien/refunct-tas/issues/65#issuecomment-706036181. - Hook the modification function: Find out which function writes the end time into the LevelState by setting a hardware breakpoint on those addresses and inspecting the backtrace. Hook the function calculating the time and perform modifications to produce the correct end time.
Find out which function writes the end time into the LevelState
UBP_MyGameInstance_C::SetTimer(int Seconds, float SecondsPartial)
Seems like this may do it, although it's a function within a Blueprint, so I don't know how you'd be able to call it. I've already looked at the functions of the last button press and it doesn't appear it's calculated with a function in that.
With the PR #160, we can send and receive SPEEDRUN_STATE::cur_time over the server and then somehow modify UBP_Outro::Title::Text [FText], which would need to be accessed... somehow.
EDIT: I can modify start time of the other players.
Another edit: we should be able to call BP_MyGameInstance_C::SetTimer(int Seconds, float SecondsPartial) as we can now call BP functions.