From 4369729d9c85fe0262d08f464e6076005c6501d4 Mon Sep 17 00:00:00 2001 From: genxium Date: Sun, 13 Nov 2022 11:37:30 +0800 Subject: [PATCH] Fixed recovery upon reconnection. --- battle_srv/models/room.go | 16 ++++--- frontend/assets/scripts/Login.js | 51 +++++++++++++-------- frontend/assets/scripts/Map.js | 61 +++++++++++++------------ frontend/assets/scripts/WsSessionMgr.js | 2 +- 4 files changed, 75 insertions(+), 55 deletions(-) diff --git a/battle_srv/models/room.go b/battle_srv/models/room.go index b4563ce..936f2a5 100644 --- a/battle_srv/models/room.go +++ b/battle_srv/models/room.go @@ -537,7 +537,8 @@ func (pR *Room) StartBattle() { 2. reconnection */ shouldResync1 := (MAGIC_LAST_SENT_INPUT_FRAME_ID_READDED == player.LastSentInputFrameId) - shouldResync2 := (0 < unconfirmedMask) // This condition is critical, if we don't send resync upon this condition, the might never get its input synced + // shouldResync2 := (0 < (unconfirmedMask & uint64(1 << uint32(player.JoinIndex-1)))) // This condition is critical, if we don't send resync upon this condition, the "reconnected or slowly-clocking player" might never get its input synced + shouldResync2 := (0 < unconfirmedMask) // An easier version of the above, might keep sending "refRenderFrame"s to still connected players when any player is disconnected if pR.BackendDynamicsEnabled && (shouldResync1 || shouldResync2) { tmp := pR.RenderFrameBuffer.GetByFrameId(refRenderFrameId) if nil == tmp { @@ -970,11 +971,12 @@ func (pR *Room) OnPlayerBattleColliderAcked(playerId int32) bool { playerMetas := make(map[int32]*PlayerDownsyncMeta, 0) for _, eachPlayer := range pR.Players { playerMetas[eachPlayer.Id] = &PlayerDownsyncMeta{ - Id: eachPlayer.Id, - Name: eachPlayer.Name, - DisplayName: eachPlayer.DisplayName, - Avatar: eachPlayer.Avatar, - JoinIndex: eachPlayer.JoinIndex, + Id: eachPlayer.Id, + Name: eachPlayer.Name, + DisplayName: eachPlayer.DisplayName, + Avatar: eachPlayer.Avatar, + JoinIndex: eachPlayer.JoinIndex, + ColliderRadius: eachPlayer.ColliderRadius, } } @@ -1251,6 +1253,8 @@ func (pR *Room) applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputF if 0 < encodedInput { Logger.Debug(fmt.Sprintf("Checking collision for playerId=%v: virtual (%d, %d) -> (%d, %d), now playerShape=%v", playerId, currPlayerDownsync.VirtualGridX, currPlayerDownsync.VirtualGridY, newVx, newVy, ConvexPolygonStr(playerCollider.Shape.(*resolv.ConvexPolygon)))) + nextRenderFramePlayers[playerId].Dir.Dx = decodedInput[0] + nextRenderFramePlayers[playerId].Dir.Dy = decodedInput[1] } } diff --git a/frontend/assets/scripts/Login.js b/frontend/assets/scripts/Login.js index 936453e..70958ee 100644 --- a/frontend/assets/scripts/Login.js +++ b/frontend/assets/scripts/Login.js @@ -86,8 +86,8 @@ cc.Class({ self.smsLoginCaptchaLabel.active = true; self.loginButton.active = true; - self.onLoginButtonClicked = self.onLoginButtonClicked.bind(self); - self.onSMSCaptchaGetButtonClicked = self.onSMSCaptchaGetButtonClicked.bind(self); + self.onLoginButtonClicked = self.onLoginButtonClicked.bind(self); + self.onSMSCaptchaGetButtonClicked = self.onSMSCaptchaGetButtonClicked.bind(self); self.smsLoginCaptchaButton.on('click', self.onSMSCaptchaGetButtonClicked); self.loadingNode = cc.instantiate(this.loadingPrefab); @@ -98,6 +98,17 @@ cc.Class({ if (null != qDict && qDict["expectedRoomId"]) { window.clearBoundRoomIdInBothVolatileAndPersistentStorage(); } + + self.checkIntAuthTokenExpire().then( + (intAuthToken) => { + console.log("Successfully found `intAuthToken` in local cache"); + self.useTokenLogin(intAuthToken); + }, + () => { + console.warn("Failed to find `intAuthToken` in local cache"); + window.clearBoundRoomIdInBothVolatileAndPersistentStorage(); + } + ); }, getRetCodeList() { @@ -185,28 +196,28 @@ cc.Class({ checkIntAuthTokenExpire() { return new Promise((resolve, reject) => { if (!cc.sys.localStorage.getItem('selfPlayer')) { - console.warn("Couldn't find selfPlayer key in local cache"); + console.warn("Couldn't find selfPlayer key in local cache"); reject(); return; } const selfPlayer = JSON.parse(cc.sys.localStorage.getItem('selfPlayer')); - if (null == selfPlayer) { - console.warn("Couldn't find selfPlayer object in local cache"); - reject(); - return; - } - - if (null == selfPlayer.intAuthToken) { - console.warn("Couldn't find selfPlayer object with key `intAuthToken` in local cache"); - reject(); - return; - } - if (new Date().getTime() > selfPlayer.expiresAt) { - console.warn("Couldn't find unexpired selfPlayer `intAuthToken` in local cache"); - reject(); - return; + if (null == selfPlayer) { + console.warn("Couldn't find selfPlayer object in local cache"); + reject(); + return; } - resolve(selfPlayer.intAuthToken); + + if (null == selfPlayer.intAuthToken) { + console.warn("Couldn't find selfPlayer object with key `intAuthToken` in local cache"); + reject(); + return; + } + if (new Date().getTime() > selfPlayer.expiresAt) { + console.warn("Couldn't find unexpired selfPlayer `intAuthToken` in local cache"); + reject(); + return; + } + resolve(selfPlayer.intAuthToken); }) }, @@ -343,7 +354,7 @@ cc.Class({ ); cc.director.loadScene('default_map'); } else { - console.log("OnLoggedIn failed, about to remove `selfPlayer` in local cache.") + console.log("OnLoggedIn failed, about to remove `selfPlayer` in local cache.") cc.sys.localStorage.removeItem("selfPlayer"); window.clearBoundRoomIdInBothVolatileAndPersistentStorage(); self.enableInteractiveControls(true); diff --git a/frontend/assets/scripts/Map.js b/frontend/assets/scripts/Map.js index f195b07..6d7deb2 100644 --- a/frontend/assets/scripts/Map.js +++ b/frontend/assets/scripts/Map.js @@ -479,32 +479,34 @@ cc.Class({ const dx = boundaryObj[i].x - x0; const dy = boundaryObj[i].y - y0; pts.push([dx, dy]); - if (self.showCriticalCoordinateLabels) { - const barrierVertLabelNode = new cc.Node(); - switch (i % 4) { - case 0: - barrierVertLabelNode.color = cc.Color.RED; - break; - case 1: - barrierVertLabelNode.color = cc.Color.GRAY; - break; - case 2: - barrierVertLabelNode.color = cc.Color.BLACK; - break; - default: - barrierVertLabelNode.color = cc.Color.MAGENTA; - break; - } - barrierVertLabelNode.setPosition(cc.v2(x0+0.95*dx, y0+0.5*dy)); - const barrierVertLabel = barrierVertLabelNode.addComponent(cc.Label); - barrierVertLabel.fontSize = 20; - barrierVertLabel.lineHeight = 22; - barrierVertLabel.string = `(${boundaryObj[i].x.toFixed(1)}, ${boundaryObj[i].y.toFixed(1)})`; - safelyAddChild(self.node, barrierVertLabelNode); - setLocalZOrder(barrierVertLabelNode, 5); - - barrierVertLabelNode.active = true; + /* + if (self.showCriticalCoordinateLabels) { + const barrierVertLabelNode = new cc.Node(); + switch (i % 4) { + case 0: + barrierVertLabelNode.color = cc.Color.RED; + break; + case 1: + barrierVertLabelNode.color = cc.Color.GRAY; + break; + case 2: + barrierVertLabelNode.color = cc.Color.BLACK; + break; + default: + barrierVertLabelNode.color = cc.Color.MAGENTA; + break; } + barrierVertLabelNode.setPosition(cc.v2(x0+0.95*dx, y0+0.5*dy)); + const barrierVertLabel = barrierVertLabelNode.addComponent(cc.Label); + barrierVertLabel.fontSize = 20; + barrierVertLabel.lineHeight = 22; + barrierVertLabel.string = `(${boundaryObj[i].x.toFixed(1)}, ${boundaryObj[i].y.toFixed(1)})`; + safelyAddChild(self.node, barrierVertLabelNode); + setLocalZOrder(barrierVertLabelNode, 5); + + barrierVertLabelNode.active = true; + } + */ } const newBarrier = self.collisionSys.createPolygon(x0, y0, pts); // console.log("Created barrier: ", newBarrier); @@ -797,8 +799,8 @@ cc.Class({ newPlayerNode.active = true; const playerScriptIns = newPlayerNode.getComponent("SelfPlayer"); playerScriptIns.scheduleNewDirection({ - dx: 0, - dy: 0 + dx: playerRichInfo.dir.dx, + dy: playerRichInfo.dir.dy }, true); return [newPlayerNode, playerScriptIns]; @@ -943,10 +945,13 @@ cc.Class({ setLocalZOrder(toShowNode, 10); }, - hideFindingPlayersGUI() { + hideFindingPlayersGUI(rdf) { const self = this; if (null == self.findingPlayerNode.parent) return; self.findingPlayerNode.parent.removeChild(self.findingPlayerNode); + if (null != rdf) { + self._initPlayerRichInfoDict(rdf.players, rdf.playerMetas); + } }, onBattleReadyToStart(rdf) { diff --git a/frontend/assets/scripts/WsSessionMgr.js b/frontend/assets/scripts/WsSessionMgr.js index 42ec8fe..30cb349 100644 --- a/frontend/assets/scripts/WsSessionMgr.js +++ b/frontend/assets/scripts/WsSessionMgr.js @@ -156,7 +156,7 @@ window.initPersistentSessionClient = function(onopenCb, expectedRoomId) { break; case window.DOWNSYNC_MSG_ACT_PLAYER_READDED_AND_ACKED: // Deliberately left blank for now - mapIns.hideFindingPlayersGUI(); + mapIns.hideFindingPlayersGUI(resp.rdf); break; case window.DOWNSYNC_MSG_ACT_BATTLE_READY_TO_START: mapIns.onBattleReadyToStart(resp.rdf);