From f36760927688bd41854c0b44ff8293286b0d4d0a Mon Sep 17 00:00:00 2001 From: genxium Date: Fri, 3 Feb 2023 22:06:03 +0800 Subject: [PATCH] Fixes for rollback on UDP peer upsync. --- frontend/assets/scripts/Map.js | 30 +++++++++++-------- .../runtime-src/Classes/udp_session.cpp | 2 +- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/frontend/assets/scripts/Map.js b/frontend/assets/scripts/Map.js index 19b201c..f8faba0 100644 --- a/frontend/assets/scripts/Map.js +++ b/frontend/assets/scripts/Map.js @@ -394,6 +394,8 @@ cc.Class({ self.networkDoctor = new NetworkDoctor(20); self.skipRenderFrameFlag = false; + self.allowRollbackOnPeerUpsync = true; + self.countdownNanos = null; if (self.countdownLabel) { self.countdownLabel.string = ""; @@ -950,18 +952,8 @@ fromUDP=${fromUDP}`); const inputFrame = batch[k]; // could be either "pb.InputFrameDownsync" or "pb.InputFrameUpsync", depending on "fromUDP" const inputFrameId = inputFrame.inputFrameId; const peerEncodedInput = (true == fromUDP ? inputFrame.encoded : inputFrame.inputList[peerJoinIndex - 1]); - if (inputFrameId <= renderedInputFrameIdUpper) { + if (false == self.allowRollbackOnPeerUpsync && inputFrameId <= renderedInputFrameIdUpper) { // [WARNING] Avoid obfuscating already rendered history, even at "inputFrameId == renderedInputFrameIdUpper", due to the use of "INPUT_SCALE_FRAMES" some previous render frames might already be rendered with "inputFrameId"! - // TODO: Shall we update the "chaserRenderFrameId" if the rendered history was wrong? It doesn't seem to impact eventual correctness if we allow the update of "chaserRenderFrameId" upon "inputFrameId <= renderedInputFrameIdUpper" here, however UDP upsync doesn't reserve order from a same sender and there might be multiple other senders, hence it might result in unnecessarily frequent chasing. - const localInputFrame = self.recentInputCache.GetByFrameId(inputFrameId); - if (null != localInputFrame - && - null == firstPredictedYetIncorrectInputFrameId - && - localInputFrame.InputList[peerJoinIndex - 1] != peerEncodedInput - ) { - firstPredictedYetIncorrectInputFrameId = inputFrameId; - } continue; } if (inputFrameId <= self.lastAllConfirmedInputFrameId) { @@ -986,12 +978,26 @@ fromUDP=${fromUDP}`); const newInputFrameDownsyncLocal = gopkgs.NewInputFrameDownsync(inputFrameId, newInputList, newConfirmedList); //console.log(`Updated encoded input of peerJoinIndex=${peerJoinIndex} to ${peerEncodedInput} for inputFrameId=${inputFrameId}/renderedInputFrameIdUpper=${renderedInputFrameIdUpper} from ${JSON.stringify(inputFrame)}; newInputFrameDownsyncLocal=${self.gopkgsInputFrameDownsyncStr(newInputFrameDownsyncLocal)}; existingInputFrame=${self.gopkgsInputFrameDownsyncStr(existingInputFrame)}`); self.recentInputCache.SetByFrameId(newInputFrameDownsyncLocal, inputFrameId); + + if (self.allowRollbackOnPeerUpsync) { + // Reaching here implies that "true == self.allowRollbackOnPeerUpsync". + // Shall we update the "chaserRenderFrameId" if the rendered history was wrong? It doesn't seem to impact eventual correctness if we allow the update of "chaserRenderFrameId" upon "inputFrameId <= renderedInputFrameIdUpper" here, however UDP upsync doesn't reserve order from a same sender and there might be multiple other senders, hence it might result in unnecessarily frequent chasing. + if ( + null == firstPredictedYetIncorrectInputFrameId + && + existingInputFrame.InputList[peerJoinIndex - 1] != peerEncodedInput + ) { + firstPredictedYetIncorrectInputFrameId = inputFrameId; + } + } } if (0 < effCnt) { //self._markConfirmationIfApplicable(); self.networkDoctor.logPeerInputFrameUpsync(batch[0].inputFrameId, batch[batch.length - 1].inputFrameId); } - self._handleIncorrectlyRenderedPrediction(firstPredictedYetIncorrectInputFrameId, batch, fromUDP); + if (true == self.allowRollbackOnPeerUpsync) { + self._handleIncorrectlyRenderedPrediction(firstPredictedYetIncorrectInputFrameId, batch, fromUDP); + } }, onPlayerAdded(rdf /* pb.RoomDownsyncFrame */ ) { diff --git a/frontend/build-templates/jsb-link/frameworks/runtime-src/Classes/udp_session.cpp b/frontend/build-templates/jsb-link/frameworks/runtime-src/Classes/udp_session.cpp index d715b9c..fd8969d 100644 --- a/frontend/build-templates/jsb-link/frameworks/runtime-src/Classes/udp_session.cpp +++ b/frontend/build-templates/jsb-link/frameworks/runtime-src/Classes/udp_session.cpp @@ -6,7 +6,7 @@ int const punchServerCnt = 3; int const punchPeerCnt = 3; -int const broadcastUpsyncCnt = 1; +int const broadcastUpsyncCnt = 2; uv_udp_t *udpRecvSocket = NULL, *udpSendSocket = NULL; uv_thread_t recvTid, sendTid;