mirror of
https://github.com/genxium/DelayNoMore
synced 2024-12-26 03:39:00 +00:00
Fixes for frontend rollback field access.
This commit is contained in:
parent
a85c6f9ad8
commit
bc8eab8115
@ -10,9 +10,12 @@ func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
ret := &pb.RoomDownsyncFrame{
|
ret := &pb.RoomDownsyncFrame{
|
||||||
Id: rdf.Id,
|
Id: rdf.Id,
|
||||||
PlayersArr: make([]*pb.PlayerDownsync, len(rdf.PlayersArr), len(rdf.PlayersArr)),
|
PlayersArr: make([]*pb.PlayerDownsync, len(rdf.PlayersArr), len(rdf.PlayersArr)),
|
||||||
MeleeBullets: make([]*pb.MeleeBullet, len(rdf.MeleeBullets), len(rdf.MeleeBullets)),
|
MeleeBullets: make([]*pb.MeleeBullet, len(rdf.MeleeBullets), len(rdf.MeleeBullets)),
|
||||||
|
CountdownNanos: rdf.CountdownNanos,
|
||||||
|
BackendUnconfirmedMask: rdf.BackendUnconfirmedMask,
|
||||||
|
ShouldForceResync: rdf.ShouldForceResync,
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, last := range rdf.PlayersArr {
|
for i, last := range rdf.PlayersArr {
|
||||||
|
@ -1160,7 +1160,7 @@ func (pR *Room) forceConfirmationIfApplicable(prevRenderFrameId int32) uint64 {
|
|||||||
pR.onInputFrameDownsyncAllConfirmed(inputFrameDownsync, -1)
|
pR.onInputFrameDownsyncAllConfirmed(inputFrameDownsync, -1)
|
||||||
}
|
}
|
||||||
if 0 < unconfirmedMask {
|
if 0 < unconfirmedMask {
|
||||||
Logger.Debug(fmt.Sprintf("[type#1 forceConfirmation] For roomId=%d@renderFrameId=%d, curDynamicsRenderFrameId=%d, LatestPlayerUpsyncedInputFrameId:%d, LastAllConfirmedInputFrameId:%d, (pR.NstDelayFrames >> pR.InputScaleFrames):%d, InputFrameUpsyncDelayTolerance:%d, unconfirmedMask=%d; there's a slow ticker suspect, forcing all-confirmation", pR.Id, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, pR.LatestPlayerUpsyncedInputFrameId, oldLastAllConfirmedInputFrameId, (pR.NstDelayFrames >> pR.InputScaleFrames), pR.InputFrameUpsyncDelayTolerance, unconfirmedMask))
|
Logger.Info(fmt.Sprintf("[type#1 forceConfirmation] For roomId=%d@renderFrameId=%d, curDynamicsRenderFrameId=%d, LatestPlayerUpsyncedInputFrameId:%d, oldLastAllConfirmedInputFrameId:%d, newLastAllConfirmedInputFrameId:%d, (pR.NstDelayFrames >> pR.InputScaleFrames):%d, InputFrameUpsyncDelayTolerance:%d, unconfirmedMask=%d; there's a slow ticker suspect, forcing all-confirmation", pR.Id, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, pR.LatestPlayerUpsyncedInputFrameId, oldLastAllConfirmedInputFrameId, pR.LastAllConfirmedInputFrameId, (pR.NstDelayFrames >> pR.InputScaleFrames), pR.InputFrameUpsyncDelayTolerance, unconfirmedMask))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Type#2 helps resolve the edge case when all players are disconnected temporarily
|
// Type#2 helps resolve the edge case when all players are disconnected temporarily
|
||||||
|
@ -605,7 +605,7 @@ cc.Class({
|
|||||||
}
|
}
|
||||||
const shouldForceDumping1 = (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.Id);
|
const shouldForceDumping1 = (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.Id);
|
||||||
let shouldForceDumping2 = (rdf.Id >= self.renderFrameId + self.renderFrameIdLagTolerance);
|
let shouldForceDumping2 = (rdf.Id >= self.renderFrameId + self.renderFrameIdLagTolerance);
|
||||||
let shouldForceResync = rdf.ShouldForceResync;
|
let shouldForceResync = pbRdf.ShouldForceResync;
|
||||||
const notSelfUnconfirmed = (0 == (rdf.BackendUnconfirmedMask & (1 << (self.selfPlayerInfo.joinIndex - 1))));
|
const notSelfUnconfirmed = (0 == (rdf.BackendUnconfirmedMask & (1 << (self.selfPlayerInfo.joinIndex - 1))));
|
||||||
if (notSelfUnconfirmed) {
|
if (notSelfUnconfirmed) {
|
||||||
shouldForceDumping2 = false;
|
shouldForceDumping2 = false;
|
||||||
@ -618,7 +618,7 @@ cc.Class({
|
|||||||
If "BackendUnconfirmedMask" is non-all-1 and contains the current player, show a label/button to hint manual reconnection. Note that the continuity of "recentInputCache" is not a good indicator, because due to network delay upon a [type#1 forceConfirmation] a player might just lag in upsync networking and have all consecutive inputFrameIds locally.
|
If "BackendUnconfirmedMask" is non-all-1 and contains the current player, show a label/button to hint manual reconnection. Note that the continuity of "recentInputCache" is not a good indicator, because due to network delay upon a [type#1 forceConfirmation] a player might just lag in upsync networking and have all consecutive inputFrameIds locally.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const [dumpRenderCacheRet, oldStRenderFrameId, oldEdRenderFrameId] = (shouldForceDumping1 || shouldForceDumping2 || shouldForceResync) ? self.recentRenderCache.setByFrameId(rdf, rdf.id) : [window.RING_BUFF_CONSECUTIVE_SET, null, null];
|
const [dumpRenderCacheRet, oldStRenderFrameId, oldEdRenderFrameId] = (shouldForceDumping1 || shouldForceDumping2 || shouldForceResync) ? self.recentRenderCache.setByFrameId(rdf, rdf.Id) : [window.RING_BUFF_CONSECUTIVE_SET, null, null];
|
||||||
if (window.RING_BUFF_FAILED_TO_SET == dumpRenderCacheRet) {
|
if (window.RING_BUFF_FAILED_TO_SET == dumpRenderCacheRet) {
|
||||||
throw `Failed to dump render cache#1 (maybe recentRenderCache too small)! rdf.id=${rdf.id}, lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}; recentRenderCache=${self._stringifyRecentRenderCache(false)}, recentInputCache=${self._stringifyRecentInputCache(false)}`;
|
throw `Failed to dump render cache#1 (maybe recentRenderCache too small)! rdf.id=${rdf.id}, lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}; recentRenderCache=${self._stringifyRecentRenderCache(false)}, recentInputCache=${self._stringifyRecentInputCache(false)}`;
|
||||||
}
|
}
|
||||||
@ -646,6 +646,8 @@ cc.Class({
|
|||||||
|
|
||||||
if (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.Id) {
|
if (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.Id) {
|
||||||
console.log('On battle started! renderFrameId=', rdf.Id);
|
console.log('On battle started! renderFrameId=', rdf.Id);
|
||||||
|
} else {
|
||||||
|
console.log('On battle resynced! renderFrameId=', rdf.Id);
|
||||||
}
|
}
|
||||||
self.renderFrameId = rdf.Id;
|
self.renderFrameId = rdf.Id;
|
||||||
self.lastRenderFrameIdTriggeredAt = performance.now();
|
self.lastRenderFrameIdTriggeredAt = performance.now();
|
||||||
@ -720,6 +722,9 @@ cc.Class({
|
|||||||
|
|
||||||
onInputFrameDownsyncBatch(batch) {
|
onInputFrameDownsyncBatch(batch) {
|
||||||
// TODO: find some kind of synchronization mechanism against "getOrPrefabInputFrameUpsync"!
|
// TODO: find some kind of synchronization mechanism against "getOrPrefabInputFrameUpsync"!
|
||||||
|
if (null == batch) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const self = this;
|
const self = this;
|
||||||
if (!self.recentInputCache) {
|
if (!self.recentInputCache) {
|
||||||
return;
|
return;
|
||||||
@ -773,7 +778,9 @@ cc.Class({
|
|||||||
*/
|
*/
|
||||||
// The actual rollback-and-chase would later be executed in update(dt).
|
// The actual rollback-and-chase would later be executed in update(dt).
|
||||||
console.warn(`Mismatched input detected, resetting chaserRenderFrameId: ${self.chaserRenderFrameId}->${renderFrameId1} by firstPredictedYetIncorrectInputFrameId: ${inputFrameId1}
|
console.warn(`Mismatched input detected, resetting chaserRenderFrameId: ${self.chaserRenderFrameId}->${renderFrameId1} by firstPredictedYetIncorrectInputFrameId: ${inputFrameId1}
|
||||||
lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}`);
|
lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}
|
||||||
|
recentInputCache=${self._stringifyRecentInputCache(false)}
|
||||||
|
batchInputFrameIdRange=[${batch[0].inputFrameId}, ${batch[batch.length - 1].inputFrameId}]`);
|
||||||
self.chaserRenderFrameId = renderFrameId1;
|
self.chaserRenderFrameId = renderFrameId1;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1104,11 +1111,11 @@ ${self._stringifyRecentInputAndRenderCacheCorrespondingly()}`);
|
|||||||
|
|
||||||
if (true == isChasing) {
|
if (true == isChasing) {
|
||||||
// [WARNING] Move the cursor "self.chaserRenderFrameId" when "true == isChasing", keep in mind that "self.chaserRenderFrameId" is not monotonic!
|
// [WARNING] Move the cursor "self.chaserRenderFrameId" when "true == isChasing", keep in mind that "self.chaserRenderFrameId" is not monotonic!
|
||||||
self.chaserRenderFrameId = nextRdf.id;
|
self.chaserRenderFrameId = nextRdf.Id;
|
||||||
} else if (nextRdf.id == self.chaserRenderFrameId + 1) {
|
} else if (nextRdf.Id == self.chaserRenderFrameId + 1) {
|
||||||
self.chaserRenderFrameId = nextRdf.id; // To avoid redundant calculation
|
self.chaserRenderFrameId = nextRdf.Id; // To avoid redundant calculation
|
||||||
}
|
}
|
||||||
self.recentRenderCache.setByFrameId(nextRdf, nextRdf.id);
|
self.recentRenderCache.setByFrameId(nextRdf, nextRdf.Id);
|
||||||
prevLatestRdf = currRdf;
|
prevLatestRdf = currRdf;
|
||||||
latestRdf = nextRdf;
|
latestRdf = nextRdf;
|
||||||
}
|
}
|
||||||
@ -1158,15 +1165,30 @@ ${self._stringifyRecentInputAndRenderCacheCorrespondingly()}`);
|
|||||||
return `[stInputFrameId=${self.recentInputCache.stFrameId}, edInputFrameId=${self.recentInputCache.edFrameId})`;
|
return `[stInputFrameId=${self.recentInputCache.stFrameId}, edInputFrameId=${self.recentInputCache.edFrameId})`;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_stringifyGopkgRoomDownsyncFrame(rdf) {
|
||||||
|
let s = [];
|
||||||
|
s.push(`{`);
|
||||||
|
s.push(` id: ${rdf.Id}`);
|
||||||
|
s.push(` players: [`);
|
||||||
|
for (let k in rdf.PlayersArr) {
|
||||||
|
const player = rdf.PlayersArr[k];
|
||||||
|
s.push(` {joinIndex: ${player.JoinIndex}, id: ${player.Id}, vx: ${player.VirtualGridX}, vy: ${player.VirtualGridY}, velX: ${player.VelX}, velY: ${player.VelY}}`);
|
||||||
|
}
|
||||||
|
s.push(` ]`);
|
||||||
|
s.push(`}`);
|
||||||
|
return s.join("\n");
|
||||||
|
},
|
||||||
|
|
||||||
_stringifyRecentRenderCache(usefullOutput) {
|
_stringifyRecentRenderCache(usefullOutput) {
|
||||||
const self = this;
|
const self = this;
|
||||||
if (true == usefullOutput) {
|
if (true == usefullOutput) {
|
||||||
let s = [];
|
let s = [];
|
||||||
for (let i = self.recentRenderCache.stFrameId; i < self.recentRenderCache.edFrameId; ++i) {
|
for (let i = self.recentRenderCache.stFrameId; i < self.recentRenderCache.edFrameId; ++i) {
|
||||||
s.push(JSON.stringify(self.recentRenderCache.getByFrameId(i)));
|
const rdf = self.recentRenderCache.getByFrameId(i);
|
||||||
|
s.push(self._stringifyGopkgRoomDownsyncFrame(rdf));
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.join('\n');
|
return s.join("\n");
|
||||||
}
|
}
|
||||||
return `[stRenderFrameId=${self.recentRenderCache.stFrameId}, edRenderFrameId=${self.recentRenderCache.edFrameId})`;
|
return `[stRenderFrameId=${self.recentRenderCache.stFrameId}, edRenderFrameId=${self.recentRenderCache.edFrameId})`;
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user