mirror of
				https://github.com/genxium/DelayNoMore
				synced 2025-11-04 05:17:52 +00:00 
			
		
		
		
	Minor fixes for rejoining signals.
This commit is contained in:
		@@ -54,6 +54,11 @@ const (
 | 
			
		||||
	COLLISION_BARRIER_INDEX_PREFIX = (1 << 16)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED = -1
 | 
			
		||||
	MAGIC_LAST_SENT_INPUT_FRAME_ID_READDED      = -2
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var DIRECTION_DECODER = [][]int32{
 | 
			
		||||
	{0, 0},
 | 
			
		||||
	{0, +1},
 | 
			
		||||
@@ -202,9 +207,9 @@ func (pR *Room) AddPlayerIfPossible(pPlayerFromDbInit *Player, session *websocke
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defer pR.onPlayerAdded(playerId)
 | 
			
		||||
	pPlayerFromDbInit.AckingFrameId = 0
 | 
			
		||||
	pPlayerFromDbInit.AckingFrameId = -1
 | 
			
		||||
	pPlayerFromDbInit.AckingInputFrameId = -1
 | 
			
		||||
	pPlayerFromDbInit.LastSentInputFrameId = -1
 | 
			
		||||
	pPlayerFromDbInit.LastSentInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
 | 
			
		||||
	pPlayerFromDbInit.BattleState = PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK
 | 
			
		||||
	pPlayerFromDbInit.FrozenAtGmtMillis = -1       // Hardcoded temporarily.
 | 
			
		||||
	pPlayerFromDbInit.Speed = PLAYER_DEFAULT_SPEED // Hardcoded temporarily.
 | 
			
		||||
@@ -236,12 +241,12 @@ func (pR *Room) ReAddPlayerIfPossible(pTmpPlayerInstance *Player, session *webso
 | 
			
		||||
	pR.PlayerDownsyncSessionDict[playerId] = session
 | 
			
		||||
	pR.PlayerSignalToCloseDict[playerId] = signalToCloseConnOfThisPlayer
 | 
			
		||||
	pEffectiveInRoomPlayerInstance := pR.Players[playerId]
 | 
			
		||||
	pEffectiveInRoomPlayerInstance.AckingFrameId = 0
 | 
			
		||||
	pEffectiveInRoomPlayerInstance.AckingFrameId = -1
 | 
			
		||||
	pEffectiveInRoomPlayerInstance.AckingInputFrameId = -1
 | 
			
		||||
	pEffectiveInRoomPlayerInstance.LastSentInputFrameId = -1
 | 
			
		||||
	pEffectiveInRoomPlayerInstance.LastSentInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_READDED
 | 
			
		||||
	pEffectiveInRoomPlayerInstance.BattleState = PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK
 | 
			
		||||
 | 
			
		||||
	Logger.Warn("ReAddPlayerIfPossible finished.", zap.Any("roomId", pR.Id), zap.Any("playerId", playerId), zap.Any("roomState", pR.State), zap.Any("roomEffectivePlayerCount", pR.EffectivePlayerCount), zap.Any("player AckingFrameId", pEffectiveInRoomPlayerInstance.AckingFrameId), zap.Any("player AckingInputFrameId", pEffectiveInRoomPlayerInstance.AckingInputFrameId))
 | 
			
		||||
	Logger.Warn("ReAddPlayerIfPossible finished.", zap.Any("roomId", pR.Id), zap.Any("playerId", playerId), zap.Any("joinIndex", pEffectiveInRoomPlayerInstance.JoinIndex), zap.Any("playerBattleState", pEffectiveInRoomPlayerInstance.BattleState), zap.Any("roomState", pR.State), zap.Any("roomEffectivePlayerCount", pR.EffectivePlayerCount), zap.Any("AckingFrameId", pEffectiveInRoomPlayerInstance.AckingFrameId), zap.Any("AckingInputFrameId", pEffectiveInRoomPlayerInstance.AckingInputFrameId), zap.Any("LastSentInputFrameId", pEffectiveInRoomPlayerInstance.LastSentInputFrameId))
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -383,7 +388,7 @@ func (pR *Room) InputsBufferString(allDetails bool) string {
 | 
			
		||||
 | 
			
		||||
func (pR *Room) StartBattle() {
 | 
			
		||||
	if RoomBattleStateIns.WAITING != pR.State {
 | 
			
		||||
		Logger.Warn("[StartBattle] Battle not started after all players' battle state checked!", zap.Any("roomId", pR.Id), zap.Any("roomState", pR.State))
 | 
			
		||||
		Logger.Warn("[StartBattle] Battle not started due to not being WAITING!", zap.Any("roomId", pR.Id), zap.Any("roomState", pR.State))
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -480,15 +485,20 @@ func (pR *Room) StartBattle() {
 | 
			
		||||
				} else {
 | 
			
		||||
					// [WARNING] Websocket is TCP-based, thus no need to re-send a previously sent inputFrame to a same player!
 | 
			
		||||
					toSendInputFrames := make([]*pb.InputFrameDownsync, 0, pR.InputsBuffer.Cnt)
 | 
			
		||||
					candidateToSendInputFrameId := atomic.LoadInt32(&(pR.Players[playerId].LastSentInputFrameId)) + 1
 | 
			
		||||
					candidateToSendInputFrameId := pR.Players[playerId].LastSentInputFrameId + 1
 | 
			
		||||
					if candidateToSendInputFrameId < pR.InputsBuffer.StFrameId {
 | 
			
		||||
						// [WARNING] As "player.LastSentInputFrameId <= lastAllConfirmedInputFrameIdWithChange" for each iteration, and "lastAllConfirmedInputFrameIdWithChange <= lastAllConfirmedInputFrameId" where the latter is used to "applyInputFrameDownsyncDynamics" and then evict "pR.InputsBuffer", thus there's a very high possibility that "player.LastSentInputFrameId" is already evicted.
 | 
			
		||||
						// Logger.Debug(fmt.Sprintf("LastSentInputFrameId already popped: roomId=%v, playerId=%v, lastSentInputFrameId=%v, playerAckingInputFrameId=%v, InputsBuffer=%v", pR.Id, playerId, candidateToSendInputFrameId-1, player.AckingInputFrameId, pR.InputsBufferString(false)))
 | 
			
		||||
						candidateToSendInputFrameId = pR.InputsBuffer.StFrameId
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					// [WARNING] EDGE CASE HERE: Upon initialization, all of "lastAllConfirmedInputFrameId", "lastAllConfirmedInputFrameIdWithChange" and "anchorInputFrameId" are "-1", thus "candidateToSendInputFrameId" starts with "0", however "inputFrameId: 0" might not have been all confirmed!
 | 
			
		||||
					if MAGIC_LAST_SENT_INPUT_FRAME_ID_READDED == player.LastSentInputFrameId {
 | 
			
		||||
						// A rejoined player, should guarantee that when it resyncs to "refRenderFrameId" a matching inputFrame to apply exists
 | 
			
		||||
						candidateToSendInputFrameId = pR.ConvertToInputFrameId(refRenderFrameId, pR.InputDelayFrames)
 | 
			
		||||
						Logger.Warn(fmt.Sprintf("Resetting refRenderFrame for rejoined player: roomId=%v, playerId=%v, refRenderFrameId=%v, candidateToSendInputFrameId=%v, upperToSendInputFrameId=%v, lastSentInputFrameId=%v, playerAckingInputFrameId=%v", pR.Id, playerId, refRenderFrameId, candidateToSendInputFrameId, upperToSendInputFrameId, player.LastSentInputFrameId, player.AckingInputFrameId))
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					// [WARNING] EDGE CASE HERE: Upon initialization, all of "lastAllConfirmedInputFrameId", "lastAllConfirmedInputFrameIdWithChange" and "anchorInputFrameId" are "-1", thus "candidateToSendInputFrameId" starts with "0", however "inputFrameId: 0" might not have been all confirmed!
 | 
			
		||||
					for candidateToSendInputFrameId <= upperToSendInputFrameId {
 | 
			
		||||
						tmp := pR.InputsBuffer.GetByFrameId(candidateToSendInputFrameId)
 | 
			
		||||
						if nil == tmp {
 | 
			
		||||
@@ -504,12 +514,17 @@ func (pR *Room) StartBattle() {
 | 
			
		||||
 | 
			
		||||
					if 0 >= len(toSendInputFrames) {
 | 
			
		||||
						// [WARNING] When sending DOWNSYNC_MSG_ACT_FORCED_RESYNC, there MUST BE accompanying "toSendInputFrames" for calculating "refRenderFrameId"!
 | 
			
		||||
 | 
			
		||||
						if MAGIC_LAST_SENT_INPUT_FRAME_ID_READDED == player.LastSentInputFrameId {
 | 
			
		||||
							Logger.Warn(fmt.Sprintf("Not sending due to empty toSendInputFrames: roomId=%v, playerId=%v, refRenderFrameId=%v, candidateToSendInputFrameId=%v, upperToSendInputFrameId=%v, lastSentInputFrameId=%v, playerAckingInputFrameId=%v", pR.Id, playerId, refRenderFrameId, candidateToSendInputFrameId, upperToSendInputFrameId, player.LastSentInputFrameId, player.AckingInputFrameId))
 | 
			
		||||
						}
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					indiceInJoinIndexBooleanArr := uint32(player.JoinIndex - 1)
 | 
			
		||||
					var joinMask uint64 = (1 << indiceInJoinIndexBooleanArr)
 | 
			
		||||
					if 0 < (unconfirmedMask & joinMask) {
 | 
			
		||||
					if MAGIC_LAST_SENT_INPUT_FRAME_ID_READDED == player.LastSentInputFrameId || 0 < (unconfirmedMask&joinMask) {
 | 
			
		||||
						// [WARNING] Even upon "MAGIC_LAST_SENT_INPUT_FRAME_ID_READDED", it could be true that "0 == (unconfirmedMask & joinMask)"!
 | 
			
		||||
						tmp := pR.RenderFrameBuffer.GetByFrameId(refRenderFrameId)
 | 
			
		||||
						if nil == tmp {
 | 
			
		||||
							panic(fmt.Sprintf("Required refRenderFrameId=%v for roomId=%v, playerId=%v, candidateToSendInputFrameId=%v doesn't exist! InputsBuffer=%v, RenderFrameBuffer=%v", refRenderFrameId, pR.Id, playerId, candidateToSendInputFrameId, pR.InputsBufferString(false), pR.RenderFrameBufferString()))
 | 
			
		||||
@@ -519,7 +534,7 @@ func (pR *Room) StartBattle() {
 | 
			
		||||
					} else {
 | 
			
		||||
						pR.sendSafely(nil, toSendInputFrames, DOWNSYNC_MSG_ACT_INPUT_BATCH, playerId)
 | 
			
		||||
					}
 | 
			
		||||
					atomic.StoreInt32(&(pR.Players[playerId].LastSentInputFrameId), candidateToSendInputFrameId-1)
 | 
			
		||||
					pR.Players[playerId].LastSentInputFrameId = candidateToSendInputFrameId - 1
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@@ -762,7 +777,7 @@ func (pR *Room) OnDismissed() {
 | 
			
		||||
	pR.RenderFrameId = 0
 | 
			
		||||
	pR.CurDynamicsRenderFrameId = 0
 | 
			
		||||
	pR.InputDelayFrames = 8
 | 
			
		||||
	pR.NstDelayFrames = 32
 | 
			
		||||
	pR.NstDelayFrames = 8
 | 
			
		||||
	pR.InputScaleFrames = uint32(2)
 | 
			
		||||
	pR.ServerFps = 60
 | 
			
		||||
	pR.RollbackEstimatedDt = float64(1.0) / float64(pR.ServerFps)
 | 
			
		||||
@@ -911,8 +926,8 @@ func (pR *Room) onPlayerReAdded(playerId int32) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (pR *Room) OnPlayerBattleColliderAcked(playerId int32) bool {
 | 
			
		||||
	targetPlayer, ok := pR.Players[playerId]
 | 
			
		||||
	if false == ok {
 | 
			
		||||
	targetPlayer, existing := pR.Players[playerId]
 | 
			
		||||
	if false == existing {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -930,10 +945,12 @@ func (pR *Room) OnPlayerBattleColliderAcked(playerId int32) bool {
 | 
			
		||||
	// Broadcast added or readded player info to all players in the same room
 | 
			
		||||
	for _, eachPlayer := range pR.Players {
 | 
			
		||||
		/*
 | 
			
		||||
		   [WARNING]
 | 
			
		||||
		   This `playerAckedFrame` is the first ever "RoomDownsyncFrame" for every "PersistentSessionClient on the frontend", and it goes right after each "BattleColliderInfo".
 | 
			
		||||
				   [WARNING]
 | 
			
		||||
				   This `playerAckedFrame` is the first ever "RoomDownsyncFrame" for every "PersistentSessionClient on the frontend", and it goes right after each "BattleColliderInfo".
 | 
			
		||||
 | 
			
		||||
		   By making use of the sequential nature of each ws session, all later "RoomDownsyncFrame"s generated after `pRoom.StartBattle()` will be put behind this `playerAckedFrame`.
 | 
			
		||||
				   By making use of the sequential nature of each ws session, all later "RoomDownsyncFrame"s generated after `pRoom.StartBattle()` will be put behind this `playerAckedFrame`.
 | 
			
		||||
 | 
			
		||||
		           This function is triggered by an upsync message via WebSocket, thus downsync sending is also available by now.
 | 
			
		||||
		*/
 | 
			
		||||
		switch targetPlayer.BattleState {
 | 
			
		||||
		case PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK:
 | 
			
		||||
@@ -955,7 +972,7 @@ func (pR *Room) OnPlayerBattleColliderAcked(playerId int32) bool {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	targetPlayer.BattleState = PlayerBattleStateIns.ACTIVE
 | 
			
		||||
	Logger.Info(fmt.Sprintf("OnPlayerBattleColliderAcked: roomId=%v, roomState=%v, targetPlayerId=%v, capacity=%v, EffectivePlayerCount=%v", pR.Id, pR.State, targetPlayer.Id, pR.Capacity, pR.EffectivePlayerCount))
 | 
			
		||||
	Logger.Info(fmt.Sprintf("OnPlayerBattleColliderAcked: roomId=%v, roomState=%v, targetPlayerId=%v, targetPlayerBattleState=%v, capacity=%v, EffectivePlayerCount=%v", pR.Id, pR.State, targetPlayer.Id, targetPlayer.BattleState, pR.Capacity, pR.EffectivePlayerCount))
 | 
			
		||||
 | 
			
		||||
	if pR.Capacity == int(pR.EffectivePlayerCount) {
 | 
			
		||||
		allAcked := true
 | 
			
		||||
@@ -1029,7 +1046,7 @@ func (pR *Room) prefabInputFrameDownsync(inputFrameId int32) *pb.InputFrameDowns
 | 
			
		||||
			InputList:     currInputList,
 | 
			
		||||
			ConfirmedList: uint64(0),
 | 
			
		||||
		}
 | 
			
		||||
	}	
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pR.InputsBuffer.Put(currInputFrameDownsync)
 | 
			
		||||
	return currInputFrameDownsync
 | 
			
		||||
@@ -1058,7 +1075,7 @@ func (pR *Room) forceConfirmationIfApplicable() uint64 {
 | 
			
		||||
		panic(fmt.Sprintf("inputFrameId2=%v doesn't exist for roomId=%v, this is abnormal because the server should prefab inputFrameDownsync in a most advanced pace, check the prefab logic! InputsBuffer=%v", inputFrameId2, pR.Id, pR.InputsBufferString(false)))
 | 
			
		||||
	}
 | 
			
		||||
	inputFrame2 := tmp.(*pb.InputFrameDownsync)
 | 
			
		||||
    for _, player := range pR.Players {
 | 
			
		||||
	for _, player := range pR.Players {
 | 
			
		||||
		// Enrich by already arrived player upsync commands
 | 
			
		||||
		bufIndex := pR.toDiscreteInputsBufferIndex(inputFrame2.InputFrameId, player.JoinIndex)
 | 
			
		||||
		tmp, loaded := pR.DiscreteInputsBuffer.LoadAndDelete(bufIndex)
 | 
			
		||||
@@ -1117,20 +1134,20 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende
 | 
			
		||||
				dx := baseChange * float64(decodedInput[0])
 | 
			
		||||
				dy := baseChange * float64(decodedInput[1])
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
				// The collision lib seems very slow at worst cases, omitting for now
 | 
			
		||||
				collisionPlayerIndex := COLLISION_PLAYER_INDEX_PREFIX + joinIndex
 | 
			
		||||
				playerCollider := pR.CollisionSysMap[collisionPlayerIndex]
 | 
			
		||||
				if collision := playerCollider.Check(dx, dy, "Barrier"); collision != nil {
 | 
			
		||||
					changeWithCollision := collision.ContactWithObject(collision.Objects[0])
 | 
			
		||||
					dx = changeWithCollision.X()
 | 
			
		||||
					dy = changeWithCollision.Y()
 | 
			
		||||
				}
 | 
			
		||||
				playerCollider.X += dx
 | 
			
		||||
				playerCollider.Y += dy
 | 
			
		||||
				// Update in "collision space"
 | 
			
		||||
				playerCollider.Update()
 | 
			
		||||
                */
 | 
			
		||||
				/*
 | 
			
		||||
					// The collision lib seems very slow at worst cases, omitting for now
 | 
			
		||||
					collisionPlayerIndex := COLLISION_PLAYER_INDEX_PREFIX + joinIndex
 | 
			
		||||
					playerCollider := pR.CollisionSysMap[collisionPlayerIndex]
 | 
			
		||||
					if collision := playerCollider.Check(dx, dy, "Barrier"); collision != nil {
 | 
			
		||||
						changeWithCollision := collision.ContactWithObject(collision.Objects[0])
 | 
			
		||||
						dx = changeWithCollision.X()
 | 
			
		||||
						dy = changeWithCollision.Y()
 | 
			
		||||
					}
 | 
			
		||||
					playerCollider.X += dx
 | 
			
		||||
					playerCollider.Y += dy
 | 
			
		||||
					// Update in "collision space"
 | 
			
		||||
					playerCollider.Update()
 | 
			
		||||
				*/
 | 
			
		||||
 | 
			
		||||
				player.Dir.Dx = decodedInput[0]
 | 
			
		||||
				player.Dir.Dy = decodedInput[1]
 | 
			
		||||
@@ -1142,7 +1159,7 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende
 | 
			
		||||
		newRenderFrame := pb.RoomDownsyncFrame{
 | 
			
		||||
			Id:             collisionSysRenderFrameId + 1,
 | 
			
		||||
			Players:        toPbPlayers(pR.Players),
 | 
			
		||||
			CountdownNanos: (pR.BattleDurationNanos - int64(collisionSysRenderFrameId)*int64(pR.RollbackEstimatedDt*1000000000)),
 | 
			
		||||
			CountdownNanos: (pR.BattleDurationNanos - int64(collisionSysRenderFrameId)*int64(pR.RollbackEstimatedDt*1000000000)), // TODO: Make this number more synced with frontend!
 | 
			
		||||
		}
 | 
			
		||||
		pR.RenderFrameBuffer.Put(&newRenderFrame)
 | 
			
		||||
		pR.CurDynamicsRenderFrameId++
 | 
			
		||||
 
 | 
			
		||||
@@ -301,6 +301,7 @@ type BattleColliderInfo struct {
 | 
			
		||||
	NstDelayFrames                  int32                     `protobuf:"varint,15,opt,name=nstDelayFrames,proto3" json:"nstDelayFrames,omitempty"`
 | 
			
		||||
	InputFrameUpsyncDelayTolerance  int32                     `protobuf:"varint,16,opt,name=inputFrameUpsyncDelayTolerance,proto3" json:"inputFrameUpsyncDelayTolerance,omitempty"`
 | 
			
		||||
	MaxChasingRenderFramesPerUpdate int32                     `protobuf:"varint,17,opt,name=maxChasingRenderFramesPerUpdate,proto3" json:"maxChasingRenderFramesPerUpdate,omitempty"`
 | 
			
		||||
	PlayerBattleState               int32                     `protobuf:"varint,18,opt,name=playerBattleState,proto3" json:"playerBattleState,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *BattleColliderInfo) Reset() {
 | 
			
		||||
@@ -454,6 +455,13 @@ func (x *BattleColliderInfo) GetMaxChasingRenderFramesPerUpdate() int32 {
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *BattleColliderInfo) GetPlayerBattleState() int32 {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.PlayerBattleState
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Player struct {
 | 
			
		||||
	state         protoimpl.MessageState
 | 
			
		||||
	sizeCache     protoimpl.SizeCache
 | 
			
		||||
@@ -1105,7 +1113,7 @@ var file_room_downsync_frame_proto_rawDesc = []byte{
 | 
			
		||||
	0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72,
 | 
			
		||||
	0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x50, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e,
 | 
			
		||||
	0x32, 0x44, 0x52, 0x0d, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x32, 0x44, 0x4c, 0x69, 0x73,
 | 
			
		||||
	0x74, 0x22, 0xd0, 0x08, 0x0a, 0x12, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c,
 | 
			
		||||
	0x74, 0x22, 0xfe, 0x08, 0x0a, 0x12, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c,
 | 
			
		||||
	0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x67,
 | 
			
		||||
	0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61,
 | 
			
		||||
	0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x68, 0x0a, 0x11, 0x73, 0x74, 0x72, 0x54, 0x6f, 0x56,
 | 
			
		||||
@@ -1161,129 +1169,132 @@ var file_room_downsync_frame_proto_rawDesc = []byte{
 | 
			
		||||
	0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x50, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74,
 | 
			
		||||
	0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x1f, 0x6d, 0x61, 0x78, 0x43, 0x68, 0x61, 0x73,
 | 
			
		||||
	0x69, 0x6e, 0x67, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x50,
 | 
			
		||||
	0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x1a, 0x60, 0x0a, 0x16, 0x53, 0x74, 0x72, 0x54,
 | 
			
		||||
	0x6f, 0x56, 0x65, 0x63, 0x32, 0x44, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74,
 | 
			
		||||
	0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
 | 
			
		||||
	0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
 | 
			
		||||
	0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75,
 | 
			
		||||
	0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x56, 0x65, 0x63, 0x32, 0x44, 0x4c, 0x69, 0x73, 0x74, 0x52,
 | 
			
		||||
	0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x68, 0x0a, 0x1a, 0x53, 0x74,
 | 
			
		||||
	0x72, 0x54, 0x6f, 0x50, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x32, 0x44, 0x4c, 0x69, 0x73, 0x74,
 | 
			
		||||
	0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
 | 
			
		||||
	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x34, 0x0a, 0x05, 0x76, 0x61,
 | 
			
		||||
	0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x72, 0x65, 0x61,
 | 
			
		||||
	0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x50, 0x6f, 0x6c, 0x79,
 | 
			
		||||
	0x67, 0x6f, 0x6e, 0x32, 0x44, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
 | 
			
		||||
	0x3a, 0x02, 0x38, 0x01, 0x22, 0x96, 0x02, 0x0a, 0x06, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12,
 | 
			
		||||
	0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x70, 0x6c, 0x61, 0x79,
 | 
			
		||||
	0x65, 0x72, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x12, 0x20,
 | 
			
		||||
	0x01, 0x28, 0x05, 0x52, 0x11, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x42, 0x61, 0x74, 0x74, 0x6c,
 | 
			
		||||
	0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x60, 0x0a, 0x16, 0x53, 0x74, 0x72, 0x54, 0x6f, 0x56,
 | 
			
		||||
	0x65, 0x63, 0x32, 0x44, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79,
 | 
			
		||||
	0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
 | 
			
		||||
	0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
 | 
			
		||||
	0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74,
 | 
			
		||||
	0x65, 0x72, 0x78, 0x2e, 0x56, 0x65, 0x63, 0x32, 0x44, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, 0x76,
 | 
			
		||||
	0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x68, 0x0a, 0x1a, 0x53, 0x74, 0x72, 0x54,
 | 
			
		||||
	0x6f, 0x50, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x32, 0x44, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61,
 | 
			
		||||
	0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
 | 
			
		||||
	0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x34, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
 | 
			
		||||
	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75,
 | 
			
		||||
	0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x50, 0x6f, 0x6c, 0x79, 0x67, 0x6f,
 | 
			
		||||
	0x6e, 0x32, 0x44, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
 | 
			
		||||
	0x38, 0x01, 0x22, 0x96, 0x02, 0x0a, 0x06, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x0e, 0x0a,
 | 
			
		||||
	0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x0c, 0x0a,
 | 
			
		||||
	0x01, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x01, 0x78, 0x12, 0x0c, 0x0a, 0x01, 0x79,
 | 
			
		||||
	0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x01, 0x79, 0x12, 0x2c, 0x0a, 0x03, 0x64, 0x69, 0x72,
 | 
			
		||||
	0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72,
 | 
			
		||||
	0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
 | 
			
		||||
	0x6f, 0x6e, 0x52, 0x03, 0x64, 0x69, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64,
 | 
			
		||||
	0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x12, 0x20, 0x0a,
 | 
			
		||||
	0x0b, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01,
 | 
			
		||||
	0x28, 0x05, 0x52, 0x0b, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12,
 | 
			
		||||
	0x2c, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x76, 0x65, 0x47, 0x6d, 0x74, 0x4d, 0x69,
 | 
			
		||||
	0x6c, 0x6c, 0x69, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x6c, 0x61, 0x73, 0x74,
 | 
			
		||||
	0x4d, 0x6f, 0x76, 0x65, 0x47, 0x6d, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x12, 0x14, 0x0a,
 | 
			
		||||
	0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x63,
 | 
			
		||||
	0x6f, 0x72, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18, 0x0b,
 | 
			
		||||
	0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x12, 0x1c, 0x0a,
 | 
			
		||||
	0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05,
 | 
			
		||||
	0x52, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x88, 0x01, 0x0a, 0x0a,
 | 
			
		||||
	0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64,
 | 
			
		||||
	0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
 | 
			
		||||
	0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20,
 | 
			
		||||
	0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20,
 | 
			
		||||
	0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65,
 | 
			
		||||
	0x12, 0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
 | 
			
		||||
	0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x6a, 0x6f, 0x69, 0x6e,
 | 
			
		||||
	0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6a, 0x6f, 0x69,
 | 
			
		||||
	0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x56, 0x0a, 0x10, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46,
 | 
			
		||||
	0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e,
 | 
			
		||||
	0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
 | 
			
		||||
	0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x1e,
 | 
			
		||||
	0x0a, 0x0a, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x44, 0x69, 0x72, 0x18, 0x06, 0x20, 0x01,
 | 
			
		||||
	0x28, 0x05, 0x52, 0x0a, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x44, 0x69, 0x72, 0x22, 0x7c,
 | 
			
		||||
	0x0a, 0x12, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e,
 | 
			
		||||
	0x73, 0x79, 0x6e, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61,
 | 
			
		||||
	0x6d, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75,
 | 
			
		||||
	0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x70, 0x75,
 | 
			
		||||
	0x74, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x52, 0x09, 0x69, 0x6e, 0x70,
 | 
			
		||||
	0x75, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72,
 | 
			
		||||
	0x6d, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x63,
 | 
			
		||||
	0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x3b, 0x0a, 0x0f,
 | 
			
		||||
	0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x12,
 | 
			
		||||
	0x28, 0x0a, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
 | 
			
		||||
	0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
 | 
			
		||||
	0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x9f, 0x03, 0x0a, 0x11, 0x52, 0x6f,
 | 
			
		||||
	0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12,
 | 
			
		||||
	0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12,
 | 
			
		||||
	0x0c, 0x0a, 0x01, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x01, 0x78, 0x12, 0x0c, 0x0a,
 | 
			
		||||
	0x01, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x01, 0x79, 0x12, 0x2c, 0x0a, 0x03, 0x64,
 | 
			
		||||
	0x69, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73,
 | 
			
		||||
	0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x44, 0x69, 0x72, 0x65, 0x63,
 | 
			
		||||
	0x74, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x64, 0x69, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x70, 0x65,
 | 
			
		||||
	0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x12,
 | 
			
		||||
	0x20, 0x0a, 0x0b, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x06,
 | 
			
		||||
	0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74,
 | 
			
		||||
	0x65, 0x12, 0x2c, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x76, 0x65, 0x47, 0x6d, 0x74,
 | 
			
		||||
	0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x6c, 0x61,
 | 
			
		||||
	0x73, 0x74, 0x4d, 0x6f, 0x76, 0x65, 0x47, 0x6d, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x12,
 | 
			
		||||
	0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05,
 | 
			
		||||
	0x73, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64,
 | 
			
		||||
	0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x12,
 | 
			
		||||
	0x1c, 0x0a, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0c, 0x20, 0x01,
 | 
			
		||||
	0x28, 0x05, 0x52, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x88, 0x01,
 | 
			
		||||
	0x0a, 0x0a, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02,
 | 
			
		||||
	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04,
 | 
			
		||||
	0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
 | 
			
		||||
	0x12, 0x20, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18,
 | 
			
		||||
	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61,
 | 
			
		||||
	0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x04, 0x20, 0x01,
 | 
			
		||||
	0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x6a, 0x6f,
 | 
			
		||||
	0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6a,
 | 
			
		||||
	0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x56, 0x0a, 0x10, 0x49, 0x6e, 0x70, 0x75,
 | 
			
		||||
	0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x22, 0x0a, 0x0c,
 | 
			
		||||
	0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01,
 | 
			
		||||
	0x28, 0x05, 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64,
 | 
			
		||||
	0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x44, 0x69, 0x72, 0x18, 0x06,
 | 
			
		||||
	0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x44, 0x69, 0x72,
 | 
			
		||||
	0x22, 0x7c, 0x0a, 0x12, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f,
 | 
			
		||||
	0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46,
 | 
			
		||||
	0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x69, 0x6e,
 | 
			
		||||
	0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e,
 | 
			
		||||
	0x70, 0x75, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x52, 0x09, 0x69,
 | 
			
		||||
	0x6e, 0x70, 0x75, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66,
 | 
			
		||||
	0x69, 0x72, 0x6d, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52,
 | 
			
		||||
	0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x3b,
 | 
			
		||||
	0x0a, 0x0f, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x55, 0x70, 0x73, 0x79, 0x6e,
 | 
			
		||||
	0x63, 0x12, 0x28, 0x0a, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73,
 | 
			
		||||
	0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x63, 0x6c, 0x69, 0x65,
 | 
			
		||||
	0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x9f, 0x03, 0x0a, 0x11,
 | 
			
		||||
	0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d,
 | 
			
		||||
	0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69,
 | 
			
		||||
	0x64, 0x12, 0x49, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03,
 | 
			
		||||
	0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e,
 | 
			
		||||
	0x74, 0x65, 0x72, 0x78, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e,
 | 
			
		||||
	0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x45, 0x6e,
 | 
			
		||||
	0x74, 0x72, 0x79, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x12, 0x26, 0x0a, 0x0e,
 | 
			
		||||
	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x03,
 | 
			
		||||
	0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x4e,
 | 
			
		||||
	0x61, 0x6e, 0x6f, 0x73, 0x12, 0x55, 0x0a, 0x0b, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65,
 | 
			
		||||
	0x74, 0x61, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x72, 0x65, 0x61,
 | 
			
		||||
	0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x52, 0x6f, 0x6f, 0x6d,
 | 
			
		||||
	0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x2e, 0x50, 0x6c,
 | 
			
		||||
	0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b,
 | 
			
		||||
	0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x73, 0x1a, 0x53, 0x0a, 0x0c, 0x50,
 | 
			
		||||
	0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
 | 
			
		||||
	0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a,
 | 
			
		||||
	0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74,
 | 
			
		||||
	0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x50,
 | 
			
		||||
	0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
 | 
			
		||||
	0x1a, 0x5b, 0x0a, 0x10, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x73, 0x45,
 | 
			
		||||
	0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
 | 
			
		||||
	0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
 | 
			
		||||
	0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65,
 | 
			
		||||
	0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65,
 | 
			
		||||
	0x74, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xca, 0x02,
 | 
			
		||||
	0x0a, 0x05, 0x57, 0x73, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64,
 | 
			
		||||
	0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x1a, 0x0a,
 | 
			
		||||
	0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52,
 | 
			
		||||
	0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x74,
 | 
			
		||||
	0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6a,
 | 
			
		||||
	0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09,
 | 
			
		||||
	0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x63, 0x6b,
 | 
			
		||||
	0x69, 0x6e, 0x67, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05,
 | 
			
		||||
	0x52, 0x0d, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12,
 | 
			
		||||
	0x2e, 0x0a, 0x12, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72,
 | 
			
		||||
	0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x61, 0x63, 0x6b,
 | 
			
		||||
	0x69, 0x6e, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12,
 | 
			
		||||
	0x57, 0x0a, 0x15, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73,
 | 
			
		||||
	0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21,
 | 
			
		||||
	0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78,
 | 
			
		||||
	0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e,
 | 
			
		||||
	0x63, 0x52, 0x15, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73,
 | 
			
		||||
	0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x30, 0x0a, 0x02, 0x68, 0x62, 0x18, 0x08,
 | 
			
		||||
	0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68,
 | 
			
		||||
	0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74,
 | 
			
		||||
	0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x02, 0x68, 0x62, 0x22, 0xa4, 0x02, 0x0a, 0x06, 0x57,
 | 
			
		||||
	0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01,
 | 
			
		||||
	0x28, 0x05, 0x52, 0x03, 0x72, 0x65, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x63, 0x68, 0x6f, 0x65,
 | 
			
		||||
	0x64, 0x4d, 0x73, 0x67, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x65, 0x63,
 | 
			
		||||
	0x68, 0x6f, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x74,
 | 
			
		||||
	0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x63, 0x74, 0x12, 0x34, 0x0a, 0x03, 0x72,
 | 
			
		||||
	0x64, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73,
 | 
			
		||||
	0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x44,
 | 
			
		||||
	0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x03, 0x72, 0x64,
 | 
			
		||||
	0x66, 0x12, 0x5d, 0x0a, 0x17, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44,
 | 
			
		||||
	0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x18, 0x05, 0x20, 0x03,
 | 
			
		||||
	0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e,
 | 
			
		||||
	0x74, 0x65, 0x72, 0x78, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44,
 | 
			
		||||
	0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x17, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72,
 | 
			
		||||
	0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68,
 | 
			
		||||
	0x12, 0x3f, 0x0a, 0x08, 0x62, 0x63, 0x69, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01,
 | 
			
		||||
	0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e,
 | 
			
		||||
	0x74, 0x65, 0x72, 0x78, 0x2e, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x69,
 | 
			
		||||
	0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x62, 0x63, 0x69, 0x46, 0x72, 0x61, 0x6d,
 | 
			
		||||
	0x65, 0x42, 0x03, 0x5a, 0x01, 0x2e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 | 
			
		||||
	0x49, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
 | 
			
		||||
	0x32, 0x2f, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65,
 | 
			
		||||
	0x72, 0x78, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46,
 | 
			
		||||
	0x72, 0x61, 0x6d, 0x65, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72,
 | 
			
		||||
	0x79, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f,
 | 
			
		||||
	0x75, 0x6e, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01,
 | 
			
		||||
	0x28, 0x03, 0x52, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x4e, 0x61, 0x6e,
 | 
			
		||||
	0x6f, 0x73, 0x12, 0x55, 0x0a, 0x0b, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61,
 | 
			
		||||
	0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75,
 | 
			
		||||
	0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f,
 | 
			
		||||
	0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x2e, 0x50, 0x6c, 0x61, 0x79,
 | 
			
		||||
	0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x70, 0x6c,
 | 
			
		||||
	0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x73, 0x1a, 0x53, 0x0a, 0x0c, 0x50, 0x6c, 0x61,
 | 
			
		||||
	0x79, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
 | 
			
		||||
	0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76,
 | 
			
		||||
	0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x72, 0x65,
 | 
			
		||||
	0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x50, 0x6c, 0x61,
 | 
			
		||||
	0x79, 0x65, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x5b,
 | 
			
		||||
	0x0a, 0x10, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x73, 0x45, 0x6e, 0x74,
 | 
			
		||||
	0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
 | 
			
		||||
	0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
 | 
			
		||||
	0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75,
 | 
			
		||||
	0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61,
 | 
			
		||||
	0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xca, 0x02, 0x0a, 0x05,
 | 
			
		||||
	0x57, 0x73, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x18, 0x01,
 | 
			
		||||
	0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70,
 | 
			
		||||
	0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70,
 | 
			
		||||
	0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x74, 0x18, 0x03,
 | 
			
		||||
	0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6a, 0x6f, 0x69,
 | 
			
		||||
	0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6a, 0x6f,
 | 
			
		||||
	0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x63, 0x6b, 0x69, 0x6e,
 | 
			
		||||
	0x67, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d,
 | 
			
		||||
	0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x2e, 0x0a,
 | 
			
		||||
	0x12, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d,
 | 
			
		||||
	0x65, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x61, 0x63, 0x6b, 0x69, 0x6e,
 | 
			
		||||
	0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x57, 0x0a,
 | 
			
		||||
	0x15, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e,
 | 
			
		||||
	0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x74,
 | 
			
		||||
	0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x49,
 | 
			
		||||
	0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x52,
 | 
			
		||||
	0x15, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e,
 | 
			
		||||
	0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x30, 0x0a, 0x02, 0x68, 0x62, 0x18, 0x08, 0x20, 0x01,
 | 
			
		||||
	0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e,
 | 
			
		||||
	0x74, 0x65, 0x72, 0x78, 0x2e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x55, 0x70,
 | 
			
		||||
	0x73, 0x79, 0x6e, 0x63, 0x52, 0x02, 0x68, 0x62, 0x22, 0xa4, 0x02, 0x0a, 0x06, 0x57, 0x73, 0x52,
 | 
			
		||||
	0x65, 0x73, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
 | 
			
		||||
	0x52, 0x03, 0x72, 0x65, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x63, 0x68, 0x6f, 0x65, 0x64, 0x4d,
 | 
			
		||||
	0x73, 0x67, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x65, 0x63, 0x68, 0x6f,
 | 
			
		||||
	0x65, 0x64, 0x4d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x74, 0x18, 0x03,
 | 
			
		||||
	0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x63, 0x74, 0x12, 0x34, 0x0a, 0x03, 0x72, 0x64, 0x66,
 | 
			
		||||
	0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72,
 | 
			
		||||
	0x65, 0x68, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x78, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f, 0x77,
 | 
			
		||||
	0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x03, 0x72, 0x64, 0x66, 0x12,
 | 
			
		||||
	0x5d, 0x0a, 0x17, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77,
 | 
			
		||||
	0x6e, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b,
 | 
			
		||||
	0x32, 0x23, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65,
 | 
			
		||||
	0x72, 0x78, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77,
 | 
			
		||||
	0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x17, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d,
 | 
			
		||||
	0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x3f,
 | 
			
		||||
	0x0a, 0x08, 0x62, 0x63, 0x69, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b,
 | 
			
		||||
	0x32, 0x23, 0x2e, 0x74, 0x72, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x68, 0x75, 0x6e, 0x74, 0x65,
 | 
			
		||||
	0x72, 0x78, 0x2e, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65,
 | 
			
		||||
	0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x62, 0x63, 0x69, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x42,
 | 
			
		||||
	0x03, 0x5a, 0x01, 0x2e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
 
 | 
			
		||||
@@ -260,6 +260,7 @@ func Serve(c *gin.Context) {
 | 
			
		||||
			NstDelayFrames:                  pRoom.NstDelayFrames,
 | 
			
		||||
			InputFrameUpsyncDelayTolerance:  pRoom.InputFrameUpsyncDelayTolerance,
 | 
			
		||||
			MaxChasingRenderFramesPerUpdate: pRoom.MaxChasingRenderFramesPerUpdate,
 | 
			
		||||
			PlayerBattleState:               pThePlayer.BattleState, // For frontend to know whether it's rejoining
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		resp := &pb.WsResp{
 | 
			
		||||
@@ -269,7 +270,7 @@ func Serve(c *gin.Context) {
 | 
			
		||||
			BciFrame:    bciFrame,
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Logger.Info("Sending downsync HeartbeatRequirements:", zap.Any("roomId", pRoom.Id), zap.Any("playerId", playerId), zap.Any("resp", resp))
 | 
			
		||||
		Logger.Debug("Sending downsync HeartbeatRequirements:", zap.Any("roomId", pRoom.Id), zap.Any("playerId", playerId), zap.Any("resp", resp))
 | 
			
		||||
 | 
			
		||||
		theBytes, marshalErr := proto.Marshal(resp)
 | 
			
		||||
		if nil != marshalErr {
 | 
			
		||||
 
 | 
			
		||||
@@ -45,6 +45,7 @@ message BattleColliderInfo {
 | 
			
		||||
  int32 nstDelayFrames        = 15;
 | 
			
		||||
  int32 inputFrameUpsyncDelayTolerance = 16;  
 | 
			
		||||
  int32 maxChasingRenderFramesPerUpdate = 17;
 | 
			
		||||
  int32 playerBattleState = 18;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message Player {
 | 
			
		||||
 
 | 
			
		||||
@@ -440,7 +440,7 @@
 | 
			
		||||
      "array": [
 | 
			
		||||
        0,
 | 
			
		||||
        0,
 | 
			
		||||
        209.57814771583418,
 | 
			
		||||
        216.50635094610968,
 | 
			
		||||
        0,
 | 
			
		||||
        0,
 | 
			
		||||
        0,
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,16 @@ window.MAGIC_ROOM_DOWNSYNC_FRAME_ID = {
 | 
			
		||||
  BATTLE_START: 0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
window.PlayerBattleState = {
 | 
			
		||||
  ADDED_PENDING_BATTLE_COLLIDER_ACK: 0,
 | 
			
		||||
  READDED_PENDING_BATTLE_COLLIDER_ACK: 1,
 | 
			
		||||
  ACTIVE: 2,
 | 
			
		||||
  DISCONNECTED: 3,
 | 
			
		||||
  LOST: 4,
 | 
			
		||||
  EXPELLED_DURING_GAME: 5,
 | 
			
		||||
  EXPELLED_IN_DISMISSAL: 6
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cc.Class({
 | 
			
		||||
  extends: cc.Component,
 | 
			
		||||
 | 
			
		||||
@@ -97,6 +107,10 @@ cc.Class({
 | 
			
		||||
      type: cc.TiledMap,
 | 
			
		||||
      default: null
 | 
			
		||||
    },
 | 
			
		||||
    renderFrameIdLagTolerance: {
 | 
			
		||||
      type: cc.Integer,
 | 
			
		||||
      default: 4 // implies (renderFrameIdLagTolerance >> inputScaleFrames) count of inputFrameIds
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  _inputFrameIdDebuggable(inputFrameId) {
 | 
			
		||||
@@ -334,10 +348,10 @@ cc.Class({
 | 
			
		||||
    window.handleClientSessionCloseOrError = function() {
 | 
			
		||||
      console.warn('+++++++ Common handleClientSessionCloseOrError()');
 | 
			
		||||
 | 
			
		||||
      if (ALL_BATTLE_STATES.IN_SETTLEMENT == self.battleState) { //如果是游戏时间结束引起的断连
 | 
			
		||||
        console.log("游戏结束引起的断连, 不需要回到登录页面");
 | 
			
		||||
      if (ALL_BATTLE_STATES.IN_SETTLEMENT == self.battleState) {
 | 
			
		||||
        console.log("Battled ended by settlement");
 | 
			
		||||
      } else {
 | 
			
		||||
        console.warn("意外断连,即将回到登录页面");
 | 
			
		||||
        console.warn("Connection lost, going back to login page");
 | 
			
		||||
        window.clearLocalStorageAndBackToLoginScene(true);
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
@@ -510,7 +524,7 @@ cc.Class({
 | 
			
		||||
    } else if (null != boundRoomId) {
 | 
			
		||||
      self.disableGameRuleNode();
 | 
			
		||||
      self.battleState = ALL_BATTLE_STATES.WAITING;
 | 
			
		||||
      window.initPersistentSessionClient(self.initAfterWSConnected, expectedRoomId);
 | 
			
		||||
      window.initPersistentSessionClient(self.initAfterWSConnected, boundRoomId);
 | 
			
		||||
    } else {
 | 
			
		||||
      self.showPopupInCanvas(self.gameRuleNode);
 | 
			
		||||
    // Deliberately left blank. -- YFLu
 | 
			
		||||
@@ -633,10 +647,11 @@ cc.Class({
 | 
			
		||||
      if (window.RING_BUFF_NON_CONSECUTIVE_SET == dumpRenderCacheRet) {
 | 
			
		||||
        // Deliberately left blank, in this case "chaserRenderFrameId" is already reset to proper value.
 | 
			
		||||
      } else {
 | 
			
		||||
        const inputFrameIdConsecutive = (inputFrameDownsyncId == self.lastAllConfirmedInputFrameId + 1);
 | 
			
		||||
        const localInputFrame = self.recentInputCache.getByFrameId(inputFrameDownsyncId);
 | 
			
		||||
        if (null == localInputFrame) {
 | 
			
		||||
          console.warn("localInputFrame not existing: recentInputCache is NOT having inputFrameDownsyncId=", inputFrameDownsyncId, "; now recentInputCache=", self._stringifyRecentInputCache(false));
 | 
			
		||||
        } else if (null == firstPredictedYetIncorrectInputFrameId && !self.equalInputLists(localInputFrame.inputList, inputFrameDownsync.inputList)) {
 | 
			
		||||
        if (null == localInputFrame && false == inputFrameIdConsecutive) {
 | 
			
		||||
          throw "localInputFrame not existing and is NOT CONSECUTIVELY EXTENDING recentInputCache: inputFrameDownsyncId=" + inputFrameDownsyncId + ", lastAllConfirmedInputFrameId=" + self.lastAllConfirmedInputFrameId + ", recentInputCache=" + self._stringifyRecentInputCache(false);
 | 
			
		||||
        } else if (null == firstPredictedYetIncorrectInputFrameId && null != localInputFrame && !self.equalInputLists(localInputFrame.inputList, inputFrameDownsync.inputList)) {
 | 
			
		||||
          firstPredictedYetIncorrectInputFrameId = inputFrameDownsyncId;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@@ -687,7 +702,7 @@ cc.Class({
 | 
			
		||||
  logBattleStats() {
 | 
			
		||||
    const self = this;
 | 
			
		||||
    let s = [];
 | 
			
		||||
    s.push("Battle stats: lastUpsyncInputFrameId=" + self.lastUpsyncInputFrameId + ", lastAllConfirmedInputFrameId=" + self.lastAllConfirmedInputFrameId);
 | 
			
		||||
    s.push("Battle stats: renderFrameId=" + self.renderFrameId + ", lastAllConfirmedRenderFrameId=" + self.lastAllConfirmedRenderFrameId + ", lastUpsyncInputFrameId=" + self.lastUpsyncInputFrameId + ", lastAllConfirmedInputFrameId=" + self.lastAllConfirmedInputFrameId);
 | 
			
		||||
 | 
			
		||||
    for (let i = self.recentInputCache.stFrameId; i < self.recentInputCache.edFrameId; ++i) {
 | 
			
		||||
      const inputFrameDownsync = self.recentInputCache.getByFrameId(i);
 | 
			
		||||
@@ -790,7 +805,7 @@ cc.Class({
 | 
			
		||||
      } finally {
 | 
			
		||||
        // Update countdown
 | 
			
		||||
        if (null != self.countdownNanos) {
 | 
			
		||||
          self.countdownNanos -= self.rollbackEstimatedDt * 1000000000;
 | 
			
		||||
          self.countdownNanos -= (performance.now() - self.lastRenderFrameIdTriggeredAt) * 1000000;
 | 
			
		||||
          if (self.countdownNanos <= 0) {
 | 
			
		||||
            self.onBattleStopped(self.playerRichInfoDict);
 | 
			
		||||
            return;
 | 
			
		||||
@@ -879,29 +894,26 @@ cc.Class({
 | 
			
		||||
    setLocalZOrder(toShowNode, 10);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onBattleReadyToStart(playerMetas, isSelfRejoining) {
 | 
			
		||||
  hideFindingPlayersGUI() {
 | 
			
		||||
    const self = this;
 | 
			
		||||
    if (null == self.findingPlayerNode.parent) return;
 | 
			
		||||
    self.findingPlayerNode.parent.removeChild(self.findingPlayerNode);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onBattleReadyToStart(playerMetas) {
 | 
			
		||||
    console.log("Calling `onBattleReadyToStart` with:", playerMetas);
 | 
			
		||||
    const self = this;
 | 
			
		||||
    const findingPlayerScriptIns = self.findingPlayerNode.getComponent("FindingPlayer");
 | 
			
		||||
    findingPlayerScriptIns.hideExitButton();
 | 
			
		||||
    findingPlayerScriptIns.updatePlayersInfo(playerMetas);
 | 
			
		||||
 | 
			
		||||
    const hideFindingPlayersGUI = function() {
 | 
			
		||||
      if (null == self.findingPlayerNode.parent) return;
 | 
			
		||||
      self.findingPlayerNode.parent.removeChild(self.findingPlayerNode);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if (true == isSelfRejoining) {
 | 
			
		||||
      hideFindingPlayersGUI();
 | 
			
		||||
    } else {
 | 
			
		||||
      // Delay to hide the "finding player" GUI, then show a countdown clock
 | 
			
		||||
      window.setTimeout(() => {
 | 
			
		||||
        hideFindingPlayersGUI();
 | 
			
		||||
        const countDownScriptIns = self.countdownToBeginGameNode.getComponent("CountdownToBeginGame");
 | 
			
		||||
        countDownScriptIns.setData();
 | 
			
		||||
        self.showPopupInCanvas(self.countdownToBeginGameNode);
 | 
			
		||||
      }, 1500);
 | 
			
		||||
    }
 | 
			
		||||
    // Delay to hide the "finding player" GUI, then show a countdown clock
 | 
			
		||||
    window.setTimeout(() => {
 | 
			
		||||
      self.hideFindingPlayersGUI();
 | 
			
		||||
      const countDownScriptIns = self.countdownToBeginGameNode.getComponent("CountdownToBeginGame");
 | 
			
		||||
      countDownScriptIns.setData();
 | 
			
		||||
      self.showPopupInCanvas(self.countdownToBeginGameNode);
 | 
			
		||||
    }, 1500);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  _createRoomDownsyncFrameLocally(renderFrameId, collisionSys, collisionSysMap) {
 | 
			
		||||
@@ -1046,7 +1058,7 @@ cc.Class({
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      latestRdf = self._createRoomDownsyncFrameLocally(i+1, collisionSys, collisionSysMap);
 | 
			
		||||
      latestRdf = self._createRoomDownsyncFrameLocally(i + 1, collisionSys, collisionSysMap);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return latestRdf;
 | 
			
		||||
 
 | 
			
		||||
@@ -166,9 +166,10 @@ window.initPersistentSessionClient = function(onopenCb, expectedRoomId) {
 | 
			
		||||
          break;
 | 
			
		||||
        case window.DOWNSYNC_MSG_ACT_PLAYER_READDED_AND_ACKED:
 | 
			
		||||
          // Deliberately left blank for now
 | 
			
		||||
          mapIns.hideFindingPlayersGUI();
 | 
			
		||||
          break;
 | 
			
		||||
        case window.DOWNSYNC_MSG_ACT_BATTLE_READY_TO_START:
 | 
			
		||||
          mapIns.onBattleReadyToStart(resp.rdf.playerMetas, false);
 | 
			
		||||
          mapIns.onBattleReadyToStart(resp.rdf.playerMetas);
 | 
			
		||||
          break;
 | 
			
		||||
        case window.DOWNSYNC_MSG_ACT_BATTLE_START:
 | 
			
		||||
          mapIns.onRoomDownsyncFrame(resp.rdf);
 | 
			
		||||
@@ -180,10 +181,22 @@ window.initPersistentSessionClient = function(onopenCb, expectedRoomId) {
 | 
			
		||||
          mapIns.onInputFrameDownsyncBatch(resp.inputFrameDownsyncBatch);
 | 
			
		||||
          break;
 | 
			
		||||
        case window.DOWNSYNC_MSG_ACT_FORCED_RESYNC:
 | 
			
		||||
          console.warn("Got forced resync@localRenderFrameId=", mapIns.renderFrameId, ", @lastAllConfirmedRenderFrameId=", mapIns.lastAllConfirmedRenderFrameId, "@lastAllConfirmedInputFrameId=", mapIns.lastAllConfirmedInputFrameId, ", @localRecentInputCache=", mapIns._stringifyRecentInputCache(false), ", the incoming resp=\n", JSON.stringify(resp));
 | 
			
		||||
          // The following order of execution is important, because "onInputFrameDownsyncBatch" is only available when state is IN_BATTLE 
 | 
			
		||||
          const dumpRenderCacheRet = mapIns.onRoomDownsyncFrame(resp.rdf);
 | 
			
		||||
          mapIns.onInputFrameDownsyncBatch(resp.inputFrameDownsyncBatch, dumpRenderCacheRet);
 | 
			
		||||
          if (null == resp.inputFrameDownsyncBatch || 0 >= resp.inputFrameDownsyncBatch.length) {
 | 
			
		||||
            console.error("Got empty inputFrameDownsyncBatch upon resync@localRenderFrameId=", mapIns.renderFrameId, ", @lastAllConfirmedRenderFrameId=", mapIns.lastAllConfirmedRenderFrameId, "@lastAllConfirmedInputFrameId=", mapIns.lastAllConfirmedInputFrameId, ", @localRecentInputCache=", mapIns._stringifyRecentInputCache(false), ", the incoming resp=\n", JSON.stringify(resp, null, 2));
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          // Unless upon ws session lost and reconnected, it's maintained true that "inputFrameDownsyncBatch[0].inputFrameId == frontend.lastAllConfirmedInputFrameId+1", and in this case we should try to keep frontend moving only by "frontend.recentInputCache" to avoid jiggling of synced positions 
 | 
			
		||||
          const inputFrameIdConsecutive = (resp.inputFrameDownsyncBatch[0].inputFrameId == mapIns.lastAllConfirmedInputFrameId + 1);
 | 
			
		||||
          const renderFrameIdConsecutive = (resp.rdf.id <= mapIns.renderFrameId + mapIns.renderFrameIdLagTolerance);
 | 
			
		||||
          if (inputFrameIdConsecutive && renderFrameIdConsecutive) {
 | 
			
		||||
            console.log("Got consecutive resync@localRenderFrameId=", mapIns.renderFrameId, ", @lastAllConfirmedRenderFrameId=", mapIns.lastAllConfirmedRenderFrameId, "@lastAllConfirmedInputFrameId=", mapIns.lastAllConfirmedInputFrameId, ", @localRecentInputCache=", mapIns._stringifyRecentInputCache(false), ", the incoming resp=\n", JSON.stringify(resp));
 | 
			
		||||
            mapIns.onInputFrameDownsyncBatch(resp.inputFrameDownsyncBatch);
 | 
			
		||||
          } else {
 | 
			
		||||
            console.warn("Got forced resync@localRenderFrameId=", mapIns.renderFrameId, ", @lastAllConfirmedRenderFrameId=", mapIns.lastAllConfirmedRenderFrameId, "@lastAllConfirmedInputFrameId=", mapIns.lastAllConfirmedInputFrameId, ", @localRecentInputCache=", mapIns._stringifyRecentInputCache(false), ", the incoming resp=\n", JSON.stringify(resp, null, 2));
 | 
			
		||||
            // The following order of execution is important 
 | 
			
		||||
            const dumpRenderCacheRet = mapIns.onRoomDownsyncFrame(resp.rdf);
 | 
			
		||||
            mapIns.onInputFrameDownsyncBatch(resp.inputFrameDownsyncBatch, dumpRenderCacheRet);
 | 
			
		||||
          }
 | 
			
		||||
          break;
 | 
			
		||||
        default:
 | 
			
		||||
          break;
 | 
			
		||||
 
 | 
			
		||||
@@ -1196,6 +1196,7 @@ $root.treasurehunterx = (function() {
 | 
			
		||||
         * @property {number|null} [nstDelayFrames] BattleColliderInfo nstDelayFrames
 | 
			
		||||
         * @property {number|null} [inputFrameUpsyncDelayTolerance] BattleColliderInfo inputFrameUpsyncDelayTolerance
 | 
			
		||||
         * @property {number|null} [maxChasingRenderFramesPerUpdate] BattleColliderInfo maxChasingRenderFramesPerUpdate
 | 
			
		||||
         * @property {number|null} [playerBattleState] BattleColliderInfo playerBattleState
 | 
			
		||||
         */
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
@@ -1351,6 +1352,14 @@ $root.treasurehunterx = (function() {
 | 
			
		||||
         */
 | 
			
		||||
        BattleColliderInfo.prototype.maxChasingRenderFramesPerUpdate = 0;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * BattleColliderInfo playerBattleState.
 | 
			
		||||
         * @member {number} playerBattleState
 | 
			
		||||
         * @memberof treasurehunterx.BattleColliderInfo
 | 
			
		||||
         * @instance
 | 
			
		||||
         */
 | 
			
		||||
        BattleColliderInfo.prototype.playerBattleState = 0;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Creates a new BattleColliderInfo instance using the specified properties.
 | 
			
		||||
         * @function create
 | 
			
		||||
@@ -1415,6 +1424,8 @@ $root.treasurehunterx = (function() {
 | 
			
		||||
                writer.uint32(/* id 16, wireType 0 =*/128).int32(message.inputFrameUpsyncDelayTolerance);
 | 
			
		||||
            if (message.maxChasingRenderFramesPerUpdate != null && Object.hasOwnProperty.call(message, "maxChasingRenderFramesPerUpdate"))
 | 
			
		||||
                writer.uint32(/* id 17, wireType 0 =*/136).int32(message.maxChasingRenderFramesPerUpdate);
 | 
			
		||||
            if (message.playerBattleState != null && Object.hasOwnProperty.call(message, "playerBattleState"))
 | 
			
		||||
                writer.uint32(/* id 18, wireType 0 =*/144).int32(message.playerBattleState);
 | 
			
		||||
            return writer;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
@@ -1555,6 +1566,10 @@ $root.treasurehunterx = (function() {
 | 
			
		||||
                        message.maxChasingRenderFramesPerUpdate = reader.int32();
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                case 18: {
 | 
			
		||||
                        message.playerBattleState = reader.int32();
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                default:
 | 
			
		||||
                    reader.skipType(tag & 7);
 | 
			
		||||
                    break;
 | 
			
		||||
@@ -1655,6 +1670,9 @@ $root.treasurehunterx = (function() {
 | 
			
		||||
            if (message.maxChasingRenderFramesPerUpdate != null && message.hasOwnProperty("maxChasingRenderFramesPerUpdate"))
 | 
			
		||||
                if (!$util.isInteger(message.maxChasingRenderFramesPerUpdate))
 | 
			
		||||
                    return "maxChasingRenderFramesPerUpdate: integer expected";
 | 
			
		||||
            if (message.playerBattleState != null && message.hasOwnProperty("playerBattleState"))
 | 
			
		||||
                if (!$util.isInteger(message.playerBattleState))
 | 
			
		||||
                    return "playerBattleState: integer expected";
 | 
			
		||||
            return null;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
@@ -1727,6 +1745,8 @@ $root.treasurehunterx = (function() {
 | 
			
		||||
                message.inputFrameUpsyncDelayTolerance = object.inputFrameUpsyncDelayTolerance | 0;
 | 
			
		||||
            if (object.maxChasingRenderFramesPerUpdate != null)
 | 
			
		||||
                message.maxChasingRenderFramesPerUpdate = object.maxChasingRenderFramesPerUpdate | 0;
 | 
			
		||||
            if (object.playerBattleState != null)
 | 
			
		||||
                message.playerBattleState = object.playerBattleState | 0;
 | 
			
		||||
            return message;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
@@ -1767,6 +1787,7 @@ $root.treasurehunterx = (function() {
 | 
			
		||||
                object.nstDelayFrames = 0;
 | 
			
		||||
                object.inputFrameUpsyncDelayTolerance = 0;
 | 
			
		||||
                object.maxChasingRenderFramesPerUpdate = 0;
 | 
			
		||||
                object.playerBattleState = 0;
 | 
			
		||||
            }
 | 
			
		||||
            if (message.stageName != null && message.hasOwnProperty("stageName"))
 | 
			
		||||
                object.stageName = message.stageName;
 | 
			
		||||
@@ -1812,6 +1833,8 @@ $root.treasurehunterx = (function() {
 | 
			
		||||
                object.inputFrameUpsyncDelayTolerance = message.inputFrameUpsyncDelayTolerance;
 | 
			
		||||
            if (message.maxChasingRenderFramesPerUpdate != null && message.hasOwnProperty("maxChasingRenderFramesPerUpdate"))
 | 
			
		||||
                object.maxChasingRenderFramesPerUpdate = message.maxChasingRenderFramesPerUpdate;
 | 
			
		||||
            if (message.playerBattleState != null && message.hasOwnProperty("playerBattleState"))
 | 
			
		||||
                object.playerBattleState = message.playerBattleState;
 | 
			
		||||
            return object;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user