diff --git a/battle_srv/models/pb_type_convert.go b/battle_srv/models/pb_type_convert.go index 52684aa..e854df8 100644 --- a/battle_srv/models/pb_type_convert.go +++ b/battle_srv/models/pb_type_convert.go @@ -2,7 +2,6 @@ package models import ( . "battle_srv/protos" - . "dnmshared/sharedprotos" ) func toPbPlayers(modelInstances map[int32]*Player, withMetaInfo bool) map[int32]*PlayerDownsync { @@ -13,13 +12,11 @@ func toPbPlayers(modelInstances map[int32]*Player, withMetaInfo bool) map[int32] for k, last := range modelInstances { toRet[k] = &PlayerDownsync{ - Id: last.Id, - VirtualGridX: last.VirtualGridX, - VirtualGridY: last.VirtualGridY, - Dir: &Direction{ - Dx: last.Dir.Dx, - Dy: last.Dir.Dy, - }, + Id: last.Id, + VirtualGridX: last.VirtualGridX, + VirtualGridY: last.VirtualGridY, + DirX: last.DirX, + DirY: last.DirY, ColliderRadius: last.ColliderRadius, Speed: last.Speed, BattleState: last.BattleState, diff --git a/battle_srv/models/player.go b/battle_srv/models/player.go index e545faa..12e6648 100644 --- a/battle_srv/models/player.go +++ b/battle_srv/models/player.go @@ -4,7 +4,6 @@ import ( . "battle_srv/protos" "battle_srv/storage" . "dnmshared" - . "dnmshared/sharedprotos" "fmt" sq "github.com/Masterminds/squirrel" "github.com/jmoiron/sqlx" @@ -64,12 +63,7 @@ func GetPlayerById(id int) (*Player, error) { func getPlayer(cond sq.Eq) (*Player, error) { p := Player{} - pd := PlayerDownsync{ - Dir: &Direction{ - Dx: 0, - Dy: 0, - }, - } + pd := PlayerDownsync{} query, args, err := sq.Select("*").From("player").Where(cond).Limit(1).ToSql() if err != nil { return nil, err diff --git a/battle_srv/models/room.go b/battle_srv/models/room.go index 5400c1e..0c535d7 100644 --- a/battle_srv/models/room.go +++ b/battle_srv/models/room.go @@ -54,6 +54,7 @@ const ( COLLISION_PLAYER_INDEX_PREFIX = (1 << 17) COLLISION_BARRIER_INDEX_PREFIX = (1 << 16) + COLLISION_BULLET_INDEX_PREFIX = (1 << 15) ) const ( @@ -1147,13 +1148,6 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende } nextRenderFrame := pR.applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputFrame, currRenderFrame, pR.CollisionSysMap) - // Update in the latest player pointers - for playerId, playerDownsync := range nextRenderFrame.Players { - pR.Players[playerId].VirtualGridX = playerDownsync.VirtualGridX - pR.Players[playerId].VirtualGridY = playerDownsync.VirtualGridY - pR.Players[playerId].Dir.Dx = playerDownsync.Dir.Dx - pR.Players[playerId].Dir.Dy = playerDownsync.Dir.Dy - } pR.RenderFrameBuffer.Put(nextRenderFrame) pR.CurDynamicsRenderFrameId++ } @@ -1166,18 +1160,23 @@ func (pR *Room) applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputF // Make a copy first for playerId, currPlayerDownsync := range currRenderFrame.Players { nextRenderFramePlayers[playerId] = &PlayerDownsync{ - Id: playerId, - VirtualGridX: currPlayerDownsync.VirtualGridX, - VirtualGridY: currPlayerDownsync.VirtualGridY, - Dir: &Direction{ - Dx: currPlayerDownsync.Dir.Dx, - Dy: currPlayerDownsync.Dir.Dy, - }, - Speed: currPlayerDownsync.Speed, - BattleState: currPlayerDownsync.BattleState, - Score: currPlayerDownsync.Score, - Removed: currPlayerDownsync.Removed, - JoinIndex: currPlayerDownsync.JoinIndex, + Id: playerId, + VirtualGridX: currPlayerDownsync.VirtualGridX, + VirtualGridY: currPlayerDownsync.VirtualGridY, + DirX: currPlayerDownsync.DirX, + DirY: currPlayerDownsync.DirY, + CharacterState: currPlayerDownsync.CharacterState, + Speed: currPlayerDownsync.Speed, + BattleState: currPlayerDownsync.BattleState, + Score: currPlayerDownsync.Score, + Removed: currPlayerDownsync.Removed, + JoinIndex: currPlayerDownsync.JoinIndex, + FramesToRecover: currPlayerDownsync.FramesToRecover - 1, + Hp: currPlayerDownsync.Hp, + MaxHp: currPlayerDownsync.MaxHp, + } + if nextRenderFramePlayers[playerId].FramesToRecover < 0 { + nextRenderFramePlayers[playerId].FramesToRecover = 0 } } @@ -1185,29 +1184,113 @@ func (pR *Room) applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputF Id: currRenderFrame.Id + 1, Players: nextRenderFramePlayers, CountdownNanos: (pR.BattleDurationNanos - int64(currRenderFrame.Id)*pR.RollbackEstimatedDtNanos), + MeleeBullets: make([]*MeleeBullet, 0), // Is there any better way to reduce malloc/free impact, e.g. smart prediction for fixed memory allocation? + } + + bulletPushbacks := make([]Vec2D, pR.Capacity) // Guaranteed determinism regardless of traversal order + effPushbacks := make([]Vec2D, pR.Capacity) // Guaranteed determinism regardless of traversal order + + // Reset playerCollider position from the "virtual grid position" + for playerId, player := range pR.Players { + joinIndex := player.JoinIndex + bulletPushbacks[joinIndex-1].X, bulletPushbacks[joinIndex-1].Y = float64(0), float64(0) + effPushbacks[joinIndex-1].X, effPushbacks[joinIndex-1].Y = float64(0), float64(0) + currPlayerDownsync := currRenderFrame.Players[playerId] + newVx, newVy := currPlayerDownsync.VirtualGridX, currPlayerDownsync.VirtualGridY + collisionPlayerIndex := COLLISION_PLAYER_INDEX_PREFIX + joinIndex + playerCollider := collisionSysMap[collisionPlayerIndex] + playerCollider.X, playerCollider.Y = VirtualGridToPolygonColliderAnchorPos(newVx, newVy, player.ColliderRadius, player.ColliderRadius, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, pR.VirtualGridToWorldRatio) + } + + // Check bullet-anything collisions first, because the pushbacks caused by bullets might later be reverted by player-barrier collision + bulletColliders := make(map[int32]*resolv.Object, 0) // Will all be removed at the end of `applyInputFrameDownsyncDynamicsOnSingleRenderFrame` due to the need for being rollback-compatible + removedBulletsAtCurrFrame := make(map[int32]int32, 0) + for _, meleeBullet := range currRenderFrame.MeleeBullets { + if (meleeBullet.OriginatedRenderFrameId+meleeBullet.StartupFrames <= currRenderFrame.Id) && (meleeBullet.OriginatedRenderFrameId+meleeBullet.StartupFrames+meleeBullet.ActiveFrames > currRenderFrame.Id) { + collisionBulletIndex := COLLISION_BULLET_INDEX_PREFIX + meleeBullet.BattleLocalId + collisionOffenderIndex := COLLISION_PLAYER_INDEX_PREFIX + meleeBullet.OffenderJoinIndex + offenderCollider := collisionSysMap[collisionOffenderIndex] + offender := currRenderFrame.Players[meleeBullet.OffenderPlayerId] + + xfac, yfac := float64(1.0), float64(0) // By now, straight Punch offset doesn't respect "y-axis" + if 0 > offender.DirX { + xfac = float64(-1.0) + } + offenderWx, offenderWy := PolygonColliderAnchorToWorldPos(offenderCollider.X, offenderCollider.Y, offender.ColliderRadius, offender.ColliderRadius, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY) + + bulletWx, bulletWy := offenderWx+xfac*meleeBullet.HitboxOffset, offenderWy+yfac*meleeBullet.HitboxOffset + + newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, xfac*meleeBullet.HitboxSize.X, meleeBullet.HitboxSize.Y, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, "MeleeBullet") + // newBulletCollider.collisionBulletIndex = collisionBulletIndex + // newBulletCollider.offenderPlayerId = meleeBullet.offenderPlayerId + // newBulletCollider.pushback = meleeBullet.pushback + // newBulletCollider.hitStunFrames = meleeBullet.hitStunFrames + collisionSysMap[collisionBulletIndex] = newBulletCollider + bulletColliders[collisionBulletIndex] = newBulletCollider + newBulletCollider.Update() + } + } + + // for _, bulletCollider := range bulletColliders { + // shouldRemove := false + // if collision := bulletCollider.Check(0, 0); collision != nil { + // bulletShape := bulletCollider.Shape.(*resolv.ConvexPolygon) + // for _, obj := range collision.Objects { + // bShape := obj.Shape.(*resolv.ConvexPolygon) + // if overlapped, pushbackX, pushbackY, overlapResult := CalcPushbacks(0, 0, bulletShape, bShape); overlapped { + // bulletPushbacks[joinIndex-1].X += pushbackX + // bulletPushbacks[joinIndex-1].Y += pushbackY + // } + // } + // shouldRemove = true + // } + // if shouldRemove { + // removedBulletsAtCurrFrame[bulletCollider.CollisionBulletIndex] = 1 + // } + // } + + for _, meleeBullet := range currRenderFrame.MeleeBullets { + collisionBulletIndex := COLLISION_BULLET_INDEX_PREFIX + meleeBullet.BattleLocalId + if bulletCollider, existent := collisionSysMap[collisionBulletIndex]; existent { + bulletCollider.Space.Remove(bulletCollider) + delete(collisionSysMap, collisionBulletIndex) + } + if _, existent := removedBulletsAtCurrFrame[collisionBulletIndex]; existent { + continue + } + toRet.MeleeBullets = append(toRet.MeleeBullets, meleeBullet) } if nil != delayedInputFrame { inputList := delayedInputFrame.InputList - effPushbacks := make([]Vec2D, pR.Capacity) // Guaranteed determinism regardless of traversal order + // Process player inputs for playerId, player := range pR.Players { joinIndex := player.JoinIndex - effPushbacks[joinIndex-1].X, effPushbacks[joinIndex-1].Y = float64(0), float64(0) - currPlayerDownsync := currRenderFrame.Players[playerId] - decodedInput := pR.decodeInput(inputList[joinIndex-1]) - proposedVirtualGridDx, proposedVirtualGridDy := (decodedInput.Dx + decodedInput.Dx*currPlayerDownsync.Speed), (decodedInput.Dy + decodedInput.Dy*currPlayerDownsync.Speed) - newVx, newVy := (currPlayerDownsync.VirtualGridX + proposedVirtualGridDx), (currPlayerDownsync.VirtualGridY + proposedVirtualGridDy) - // Reset playerCollider position from the "virtual grid position" collisionPlayerIndex := COLLISION_PLAYER_INDEX_PREFIX + joinIndex playerCollider := collisionSysMap[collisionPlayerIndex] - playerCollider.X, playerCollider.Y = VirtualGridToPolygonColliderAnchorPos(newVx, newVy, player.ColliderRadius, player.ColliderRadius, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, pR.VirtualGridToWorldRatio) + if 0 < nextRenderFramePlayers[playerId].FramesToRecover { + // No need to process inputs for this player, but there might be bullet pushbacks on this player + playerCollider.X += bulletPushbacks[joinIndex-1].X + playerCollider.Y += bulletPushbacks[joinIndex-1].Y + continue + } + currPlayerDownsync := currRenderFrame.Players[playerId] + decodedInput := pR.decodeInput(inputList[joinIndex-1]) + + if 0 != decodedInput.Dx || 0 != decodedInput.Dy { + nextRenderFramePlayers[playerId].DirX = decodedInput.Dx + nextRenderFramePlayers[playerId].DirY = decodedInput.Dy + nextRenderFramePlayers[playerId].CharacterState = 1 + } else { + nextRenderFramePlayers[playerId].CharacterState = 0 + } + + movementX, movementY := VirtualGridToWorldPos(decodedInput.Dx+decodedInput.Dx*currPlayerDownsync.Speed, decodedInput.Dy+decodedInput.Dy*currPlayerDownsync.Speed, pR.VirtualGridToWorldRatio) + playerCollider.X += movementX + playerCollider.Y += movementY // Update in the collision system playerCollider.Update() - if 0 != decodedInput.Dx || 0 != decodedInput.Dy { - nextRenderFramePlayers[playerId].Dir.Dx = decodedInput.Dx - nextRenderFramePlayers[playerId].Dir.Dy = decodedInput.Dy - } } // handle pushbacks upon collision after all movements treated as simultaneous diff --git a/battle_srv/protos/room_downsync_frame.pb.go b/battle_srv/protos/room_downsync_frame.pb.go index 86bc8e7..9a37967 100644 --- a/battle_srv/protos/room_downsync_frame.pb.go +++ b/battle_srv/protos/room_downsync_frame.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.28.1 -// protoc v3.7.1 +// protoc v3.21.4 // source: room_downsync_frame.proto package protos @@ -257,24 +257,25 @@ type PlayerDownsync struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - VirtualGridX int32 `protobuf:"varint,2,opt,name=virtualGridX,proto3" json:"virtualGridX,omitempty"` - VirtualGridY int32 `protobuf:"varint,3,opt,name=virtualGridY,proto3" json:"virtualGridY,omitempty"` - Dir *sharedprotos.Direction `protobuf:"bytes,4,opt,name=dir,proto3" json:"dir,omitempty"` - Speed int32 `protobuf:"varint,5,opt,name=speed,proto3" json:"speed,omitempty"` // in terms of virtual grid units - BattleState int32 `protobuf:"varint,6,opt,name=battleState,proto3" json:"battleState,omitempty"` - JoinIndex int32 `protobuf:"varint,7,opt,name=joinIndex,proto3" json:"joinIndex,omitempty"` - ColliderRadius float64 `protobuf:"fixed64,8,opt,name=colliderRadius,proto3" json:"colliderRadius,omitempty"` - Removed bool `protobuf:"varint,9,opt,name=removed,proto3" json:"removed,omitempty"` - Score int32 `protobuf:"varint,10,opt,name=score,proto3" json:"score,omitempty"` - LastMoveGmtMillis int32 `protobuf:"varint,11,opt,name=lastMoveGmtMillis,proto3" json:"lastMoveGmtMillis,omitempty"` - FramesToRecover int32 `protobuf:"varint,12,opt,name=framesToRecover,proto3" json:"framesToRecover,omitempty"` - Hp int32 `protobuf:"varint,13,opt,name=hp,proto3" json:"hp,omitempty"` - MaxHp int32 `protobuf:"varint,14,opt,name=maxHp,proto3" json:"maxHp,omitempty"` - CharacterState int32 `protobuf:"varint,15,opt,name=characterState,proto3" json:"characterState,omitempty"` - Name string `protobuf:"bytes,16,opt,name=name,proto3" json:"name,omitempty"` - DisplayName string `protobuf:"bytes,17,opt,name=displayName,proto3" json:"displayName,omitempty"` - Avatar string `protobuf:"bytes,18,opt,name=avatar,proto3" json:"avatar,omitempty"` + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + VirtualGridX int32 `protobuf:"varint,2,opt,name=virtualGridX,proto3" json:"virtualGridX,omitempty"` + VirtualGridY int32 `protobuf:"varint,3,opt,name=virtualGridY,proto3" json:"virtualGridY,omitempty"` + DirX int32 `protobuf:"varint,4,opt,name=dirX,proto3" json:"dirX,omitempty"` + DirY int32 `protobuf:"varint,5,opt,name=dirY,proto3" json:"dirY,omitempty"` + Speed int32 `protobuf:"varint,6,opt,name=speed,proto3" json:"speed,omitempty"` // in terms of virtual grid units + BattleState int32 `protobuf:"varint,7,opt,name=battleState,proto3" json:"battleState,omitempty"` + JoinIndex int32 `protobuf:"varint,8,opt,name=joinIndex,proto3" json:"joinIndex,omitempty"` + ColliderRadius float64 `protobuf:"fixed64,9,opt,name=colliderRadius,proto3" json:"colliderRadius,omitempty"` + Removed bool `protobuf:"varint,10,opt,name=removed,proto3" json:"removed,omitempty"` + Score int32 `protobuf:"varint,11,opt,name=score,proto3" json:"score,omitempty"` + LastMoveGmtMillis int32 `protobuf:"varint,12,opt,name=lastMoveGmtMillis,proto3" json:"lastMoveGmtMillis,omitempty"` + FramesToRecover int32 `protobuf:"varint,13,opt,name=framesToRecover,proto3" json:"framesToRecover,omitempty"` + Hp int32 `protobuf:"varint,14,opt,name=hp,proto3" json:"hp,omitempty"` + MaxHp int32 `protobuf:"varint,15,opt,name=maxHp,proto3" json:"maxHp,omitempty"` + CharacterState int32 `protobuf:"varint,16,opt,name=characterState,proto3" json:"characterState,omitempty"` + Name string `protobuf:"bytes,17,opt,name=name,proto3" json:"name,omitempty"` + DisplayName string `protobuf:"bytes,18,opt,name=displayName,proto3" json:"displayName,omitempty"` + Avatar string `protobuf:"bytes,19,opt,name=avatar,proto3" json:"avatar,omitempty"` } func (x *PlayerDownsync) Reset() { @@ -330,11 +331,18 @@ func (x *PlayerDownsync) GetVirtualGridY() int32 { return 0 } -func (x *PlayerDownsync) GetDir() *sharedprotos.Direction { +func (x *PlayerDownsync) GetDirX() int32 { if x != nil { - return x.Dir + return x.DirX } - return nil + return 0 +} + +func (x *PlayerDownsync) GetDirY() int32 { + if x != nil { + return x.DirY + } + return 0 } func (x *PlayerDownsync) GetSpeed() int32 { @@ -1198,167 +1206,166 @@ var file_room_downsync_frame_proto_rawDesc = []byte{ 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 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, 0xb5, 0x04, 0x0a, 0x0e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x6f, 0x77, + 0x38, 0x01, 0x22, 0xb2, 0x04, 0x0a, 0x0e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x58, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x58, 0x12, 0x22, 0x0a, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x59, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x59, 0x12, 0x29, 0x0a, - 0x03, 0x64, 0x69, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x68, 0x61, - 0x72, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 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, 0x05, 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, 0x1c, 0x0a, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x26, - 0x0a, 0x0e, 0x63, 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72, - 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, - 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x4d, 0x6f, - 0x76, 0x65, 0x47, 0x6d, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x76, 0x65, 0x47, 0x6d, 0x74, 0x4d, 0x69, - 0x6c, 0x6c, 0x69, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x54, 0x6f, - 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x66, - 0x72, 0x61, 0x6d, 0x65, 0x73, 0x54, 0x6f, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x12, 0x0e, - 0x0a, 0x02, 0x68, 0x70, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x68, 0x70, 0x12, 0x14, - 0x0a, 0x05, 0x6d, 0x61, 0x78, 0x48, 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d, - 0x61, 0x78, 0x48, 0x70, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, - 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x63, 0x68, - 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x10, 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, - 0x11, 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, 0x12, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x22, 0x51, 0x0a, 0x11, 0x49, 0x6e, - 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x12, - 0x0e, 0x0a, 0x02, 0x64, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x64, 0x78, 0x12, - 0x0e, 0x0a, 0x02, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x64, 0x79, 0x12, - 0x1c, 0x0a, 0x09, 0x62, 0x74, 0x6e, 0x41, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x09, 0x62, 0x74, 0x6e, 0x41, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x50, 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, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 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, 0xb8, 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, 0x4e, 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, 0x18, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x73, 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, 0x27, 0x0a, 0x02, - 0x68, 0x62, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x73, 0x2e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x55, 0x70, 0x73, 0x79, 0x6e, - 0x63, 0x52, 0x02, 0x68, 0x62, 0x22, 0x89, 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, 0x2b, 0x0a, 0x03, 0x72, 0x64, 0x66, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x52, 0x6f, 0x6f, - 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x03, - 0x72, 0x64, 0x66, 0x12, 0x54, 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, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 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, 0x36, 0x0a, 0x08, 0x62, 0x63, 0x69, - 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x73, 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, 0x22, 0xe5, 0x05, 0x0a, 0x0b, 0x4d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, - 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, - 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, - 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x75, 0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x22, 0x0a, - 0x0c, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, - 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x72, 0x61, - 0x6d, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x72, 0x65, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x15, 0x72, 0x65, 0x63, - 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x4f, 0x6e, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x4f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, - 0x30, 0x0a, 0x13, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, - 0x73, 0x4f, 0x6e, 0x48, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x13, 0x72, 0x65, - 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x4f, 0x6e, 0x48, 0x69, - 0x74, 0x12, 0x35, 0x0a, 0x0b, 0x6d, 0x6f, 0x76, 0x65, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x56, 0x65, 0x63, 0x32, 0x44, 0x52, 0x0b, 0x6d, 0x6f, 0x76, - 0x65, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x68, 0x69, 0x74, 0x62, - 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, - 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x33, 0x0a, 0x0a, - 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, - 0x56, 0x65, 0x63, 0x32, 0x44, 0x52, 0x0a, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, - 0x65, 0x12, 0x38, 0x0a, 0x17, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x52, - 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x17, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, - 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x68, - 0x69, 0x74, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x0d, 0x68, 0x69, 0x74, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, - 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, - 0x61, 0x6d, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, - 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x70, - 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x2e, 0x0a, 0x12, 0x72, 0x65, 0x6c, 0x65, 0x61, - 0x73, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x18, 0x0e, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x12, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, 0x72, 0x69, 0x67, - 0x67, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, - 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x12, - 0x2c, 0x0a, 0x11, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, - 0x6e, 0x64, 0x65, 0x78, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x6f, 0x66, 0x66, 0x65, - 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2a, 0x0a, - 0x10, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, - 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, - 0x72, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x22, 0x9a, 0x02, 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, - 0x40, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 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, 0x37, 0x0a, 0x0c, 0x6d, 0x65, 0x6c, - 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, - 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x0c, 0x6d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, - 0x74, 0x73, 0x1a, 0x52, 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, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x50, 0x6c, 0x61, - 0x79, 0x65, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x13, 0x5a, 0x11, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, - 0x5f, 0x73, 0x72, 0x76, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x59, 0x12, 0x12, 0x0a, + 0x04, 0x64, 0x69, 0x72, 0x58, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x64, 0x69, 0x72, + 0x58, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x69, 0x72, 0x59, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x04, 0x64, 0x69, 0x72, 0x59, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x62, + 0x61, 0x74, 0x74, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x0b, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x0a, + 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x26, 0x0a, 0x0e, 0x63, + 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x52, 0x61, 0x64, + 0x69, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x63, + 0x6f, 0x72, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x76, 0x65, 0x47, + 0x6d, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, + 0x6c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x76, 0x65, 0x47, 0x6d, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, + 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x54, 0x6f, 0x52, 0x65, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x66, 0x72, 0x61, 0x6d, + 0x65, 0x73, 0x54, 0x6f, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x68, + 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x68, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x6d, + 0x61, 0x78, 0x48, 0x70, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d, 0x61, 0x78, 0x48, + 0x70, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x63, 0x68, 0x61, 0x72, 0x61, + 0x63, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x11, 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, 0x12, 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, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x22, 0x51, 0x0a, 0x11, 0x49, 0x6e, 0x70, 0x75, 0x74, + 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, + 0x64, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x64, 0x78, 0x12, 0x0e, 0x0a, 0x02, + 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x64, 0x79, 0x12, 0x1c, 0x0a, 0x09, + 0x62, 0x74, 0x6e, 0x41, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x09, 0x62, 0x74, 0x6e, 0x41, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x50, 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, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 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, 0xb8, 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, 0x4e, 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, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x73, 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, 0x27, 0x0a, 0x02, 0x68, 0x62, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48, + 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x02, + 0x68, 0x62, 0x22, 0x89, 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, 0x2b, 0x0a, 0x03, 0x72, 0x64, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f, + 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x03, 0x72, 0x64, 0x66, + 0x12, 0x54, 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, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 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, 0x36, 0x0a, 0x08, 0x62, 0x63, 0x69, 0x46, 0x72, 0x61, + 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x73, 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, 0x22, 0xe5, + 0x05, 0x0a, 0x0b, 0x4d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x12, 0x24, + 0x0a, 0x0d, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x4c, 0x6f, 0x63, + 0x61, 0x6c, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46, + 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x75, 0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x26, + 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, + 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x15, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, + 0x72, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x4f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, + 0x72, 0x61, 0x6d, 0x65, 0x73, 0x4f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x30, 0x0a, 0x13, + 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x4f, 0x6e, + 0x48, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x13, 0x72, 0x65, 0x63, 0x6f, 0x76, + 0x65, 0x72, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x4f, 0x6e, 0x48, 0x69, 0x74, 0x12, 0x35, + 0x0a, 0x0b, 0x6d, 0x6f, 0x76, 0x65, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x73, 0x2e, 0x56, 0x65, 0x63, 0x32, 0x44, 0x52, 0x0b, 0x6d, 0x6f, 0x76, 0x65, 0x66, 0x6f, + 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x68, 0x69, 0x74, + 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x33, 0x0a, 0x0a, 0x68, 0x69, 0x74, + 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, + 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x56, 0x65, 0x63, + 0x32, 0x44, 0x52, 0x0a, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x38, + 0x0a, 0x17, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x17, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74, 0x53, + 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x0d, 0x68, 0x69, 0x74, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x28, + 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, + 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, + 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x75, 0x73, 0x68, + 0x62, 0x61, 0x63, 0x6b, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x70, 0x75, 0x73, 0x68, + 0x62, 0x61, 0x63, 0x6b, 0x12, 0x2e, 0x0a, 0x12, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, + 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x12, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x0f, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, 0x11, + 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2a, 0x0a, 0x10, 0x6f, 0x66, + 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x18, 0x11, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x50, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x22, 0x9a, 0x02, 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, 0x40, 0x0a, 0x07, + 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 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, 0x37, 0x0a, 0x0c, 0x6d, 0x65, 0x6c, 0x65, 0x65, 0x42, + 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, + 0x74, 0x52, 0x0c, 0x6d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x1a, + 0x52, 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, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, + 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x42, 0x13, 0x5a, 0x11, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x5f, 0x73, 0x72, + 0x76, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1388,32 +1395,30 @@ var file_room_downsync_frame_proto_goTypes = []interface{}{ nil, // 10: protos.BattleColliderInfo.StrToVec2DListMapEntry nil, // 11: protos.BattleColliderInfo.StrToPolygon2DListMapEntry nil, // 12: protos.RoomDownsyncFrame.PlayersEntry - (*sharedprotos.Direction)(nil), // 13: sharedprotos.Direction - (*sharedprotos.Vec2D)(nil), // 14: sharedprotos.Vec2D - (*sharedprotos.Vec2DList)(nil), // 15: sharedprotos.Vec2DList - (*sharedprotos.Polygon2DList)(nil), // 16: sharedprotos.Polygon2DList + (*sharedprotos.Vec2D)(nil), // 13: sharedprotos.Vec2D + (*sharedprotos.Vec2DList)(nil), // 14: sharedprotos.Vec2DList + (*sharedprotos.Polygon2DList)(nil), // 15: sharedprotos.Polygon2DList } var file_room_downsync_frame_proto_depIdxs = []int32{ 10, // 0: protos.BattleColliderInfo.strToVec2DListMap:type_name -> protos.BattleColliderInfo.StrToVec2DListMapEntry 11, // 1: protos.BattleColliderInfo.strToPolygon2DListMap:type_name -> protos.BattleColliderInfo.StrToPolygon2DListMapEntry - 13, // 2: protos.PlayerDownsync.dir:type_name -> sharedprotos.Direction - 3, // 3: protos.WsReq.inputFrameUpsyncBatch:type_name -> protos.InputFrameUpsync - 5, // 4: protos.WsReq.hb:type_name -> protos.HeartbeatUpsync - 9, // 5: protos.WsResp.rdf:type_name -> protos.RoomDownsyncFrame - 4, // 6: protos.WsResp.inputFrameDownsyncBatch:type_name -> protos.InputFrameDownsync - 0, // 7: protos.WsResp.bciFrame:type_name -> protos.BattleColliderInfo - 14, // 8: protos.MeleeBullet.moveforward:type_name -> sharedprotos.Vec2D - 14, // 9: protos.MeleeBullet.hitboxSize:type_name -> sharedprotos.Vec2D - 12, // 10: protos.RoomDownsyncFrame.players:type_name -> protos.RoomDownsyncFrame.PlayersEntry - 8, // 11: protos.RoomDownsyncFrame.meleeBullets:type_name -> protos.MeleeBullet - 15, // 12: protos.BattleColliderInfo.StrToVec2DListMapEntry.value:type_name -> sharedprotos.Vec2DList - 16, // 13: protos.BattleColliderInfo.StrToPolygon2DListMapEntry.value:type_name -> sharedprotos.Polygon2DList - 1, // 14: protos.RoomDownsyncFrame.PlayersEntry.value:type_name -> protos.PlayerDownsync - 15, // [15:15] is the sub-list for method output_type - 15, // [15:15] is the sub-list for method input_type - 15, // [15:15] is the sub-list for extension type_name - 15, // [15:15] is the sub-list for extension extendee - 0, // [0:15] is the sub-list for field type_name + 3, // 2: protos.WsReq.inputFrameUpsyncBatch:type_name -> protos.InputFrameUpsync + 5, // 3: protos.WsReq.hb:type_name -> protos.HeartbeatUpsync + 9, // 4: protos.WsResp.rdf:type_name -> protos.RoomDownsyncFrame + 4, // 5: protos.WsResp.inputFrameDownsyncBatch:type_name -> protos.InputFrameDownsync + 0, // 6: protos.WsResp.bciFrame:type_name -> protos.BattleColliderInfo + 13, // 7: protos.MeleeBullet.moveforward:type_name -> sharedprotos.Vec2D + 13, // 8: protos.MeleeBullet.hitboxSize:type_name -> sharedprotos.Vec2D + 12, // 9: protos.RoomDownsyncFrame.players:type_name -> protos.RoomDownsyncFrame.PlayersEntry + 8, // 10: protos.RoomDownsyncFrame.meleeBullets:type_name -> protos.MeleeBullet + 14, // 11: protos.BattleColliderInfo.StrToVec2DListMapEntry.value:type_name -> sharedprotos.Vec2DList + 15, // 12: protos.BattleColliderInfo.StrToPolygon2DListMapEntry.value:type_name -> sharedprotos.Polygon2DList + 1, // 13: protos.RoomDownsyncFrame.PlayersEntry.value:type_name -> protos.PlayerDownsync + 14, // [14:14] is the sub-list for method output_type + 14, // [14:14] is the sub-list for method input_type + 14, // [14:14] is the sub-list for extension type_name + 14, // [14:14] is the sub-list for extension extendee + 0, // [0:14] is the sub-list for field type_name } func init() { file_room_downsync_frame_proto_init() } diff --git a/dnmshared/sharedprotos/geometry.pb.go b/dnmshared/sharedprotos/geometry.pb.go index e3aedc9..b96f64b 100644 --- a/dnmshared/sharedprotos/geometry.pb.go +++ b/dnmshared/sharedprotos/geometry.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.28.1 -// protoc v3.7.1 +// protoc v3.21.4 // source: geometry.proto package sharedprotos diff --git a/frontend/assets/resources/map/dungeon/map.tmx b/frontend/assets/resources/map/dungeon/map.tmx index 3f6bc43..60573ed 100644 --- a/frontend/assets/resources/map/dungeon/map.tmx +++ b/frontend/assets/resources/map/dungeon/map.tmx @@ -1,17 +1,18 @@ - + - + + - eJzt0jEOwjAUREGLkiLmALRU3In7HwMKkFCUCCwiNrKnmCbVvh8fSikHAAAA/qruYEOr84Zd+vM9re0v+vXr1z9S/7f0l3KZ9dXZ91r67QeAXxyf0jv0Z/tvO9iS7F+T3ucG+Xuk96RvkN4CMJLaIL0VttLy7r19euHdA+zX6YP0vlR3z/3ax2tfarw+TAO0L/VPb3ruXvv3o7z7lv70zuQN0vtgz+6DDSsZ + eJzt2q1u22AYhuEo1UhBtYFWKh/bmRRMRYNFPZPxwcKi7jznSInkWk7teG5ex88FLhQD570d5/PP1WazuQIAAAAAAAAAAAAAAAAAgAmu96r3g/N5bjn0fw5U3aGy/3bv0P+p8XDEdoX0f9//GP3Xp93/YaD/9QJa6f95/fvov26773671zeb7jmhupX+5+2fQH/9qztU9v8yQXUz/fXXX3/9a/ovgf7666+//vrrf1n9/4zc7tue/uvq/9Z4PfLZ7vnz38ZP/cv7T53p4Z7i7/+kv/7667/bl/sO/dff/77T3+9ff/3r+38dMGf/Nv1r+w917+v/0vh1okN/67/l9B/b/nFj/X8pxvYf236r/0UZ6t/X+Efj5kj7bv+uxxPpX9e/r/1NS7f7Z/S/a3zXfzH9Pzrvt/vPTf/l9p+yRjyV/ufvP+YY6M5yzr5D5uy/XUCLJfafa8YfmdJe//X0r6Z/9jGgv/7661/doqp/9fyrpV//Vc+/mv7Z9M+mfzb9s+mfTf9s+mfTP5v+2fTPpn82/bPpn03/bPpn0z+b/tn0z6Z/Nv2z6Z/N+9/Z9M+mfzb//9n0z6Z/Nv2z6Z9N/2z6Z9M/m/7Z0vtT3wEAAAAAAAAAAAAAAAA4v39IY4NC - + - + @@ -19,71 +20,149 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/assets/resources/map/dungeon/tiles2.tsx b/frontend/assets/resources/map/dungeon/tiles2.tsx new file mode 100644 index 0000000..6016271 --- /dev/null +++ b/frontend/assets/resources/map/dungeon/tiles2.tsx @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/assets/resources/map/dungeon/tiles2.tsx.meta b/frontend/assets/resources/map/dungeon/tiles2.tsx.meta new file mode 100644 index 0000000..9092881 --- /dev/null +++ b/frontend/assets/resources/map/dungeon/tiles2.tsx.meta @@ -0,0 +1,5 @@ +{ + "ver": "2.0.0", + "uuid": "2e53500f-f9c8-4b5b-b74c-f2adbc2ec34d", + "subMetas": {} +} \ No newline at end of file diff --git a/frontend/assets/resources/pbfiles/room_downsync_frame.proto b/frontend/assets/resources/pbfiles/room_downsync_frame.proto index 88ad1cc..ca476a8 100644 --- a/frontend/assets/resources/pbfiles/room_downsync_frame.proto +++ b/frontend/assets/resources/pbfiles/room_downsync_frame.proto @@ -38,22 +38,23 @@ message PlayerDownsync { int32 id = 1; int32 virtualGridX = 2; int32 virtualGridY = 3; - sharedprotos.Direction dir = 4; - int32 speed = 5; // in terms of virtual grid units - int32 battleState = 6; - int32 joinIndex = 7; - double colliderRadius = 8; - bool removed = 9; - int32 score = 10; - int32 lastMoveGmtMillis = 11; - int32 framesToRecover = 12; - int32 hp = 13; - int32 maxHp = 14; - int32 characterState = 15; + int32 dirX = 4; + int32 dirY = 5; + int32 speed = 6; // in terms of virtual grid units + int32 battleState = 7; + int32 joinIndex = 8; + double colliderRadius = 9; + bool removed = 10; + int32 score = 11; + int32 lastMoveGmtMillis = 12; + int32 framesToRecover = 13; + int32 hp = 14; + int32 maxHp = 15; + int32 characterState = 16; - string name = 16; - string displayName = 17; - string avatar = 18; + string name = 17; + string displayName = 18; + string avatar = 19; } message InputFrameDecoded { @@ -123,8 +124,6 @@ message MeleeBullet { int32 offenderJoinIndex = 16; int32 offenderPlayerId = 17; - - int32 offenderPlayerId = 17; } message RoomDownsyncFrame { diff --git a/frontend/assets/scenes/offline_map_1.fire b/frontend/assets/scenes/offline_map_1.fire index eda2fde..0ac0a62 100644 --- a/frontend/assets/scenes/offline_map_1.fire +++ b/frontend/assets/scenes/offline_map_1.fire @@ -277,6 +277,7 @@ "forceBigEndianFloatingNumDecoding": false, "renderFrameIdLagTolerance": 4, "jigglingEps1D": 0.001, + "bulletTriggerEnabled": true, "_id": "4b+kZ46VhC0LCBixXEK2dk" }, { diff --git a/frontend/assets/scripts/Map.js b/frontend/assets/scripts/Map.js index 75b79ef..8cf2031 100644 --- a/frontend/assets/scripts/Map.js +++ b/frontend/assets/scripts/Map.js @@ -95,6 +95,9 @@ cc.Class({ type: cc.Float, default: 1e-3 }, + bulletTriggerEnabled: { + default: false + }, }, _inputFrameIdDebuggable(inputFrameId) { @@ -321,10 +324,10 @@ cc.Class({ self.battleState = ALL_BATTLE_STATES.WAITING; + self.countdownNanos = null; if (self.countdownLabel) { self.countdownLabel.string = ""; } - self.countdownNanos = null; if (self.findingPlayerNode) { const findingPlayerScriptIns = self.findingPlayerNode.getComponent("FindingPlayer"); findingPlayerScriptIns.init(); @@ -741,17 +744,15 @@ cc.Class({ self.playersInfoNode.getComponent("PlayersInfo").clearInfo(); }, - spawnPlayerNode(joinIndex, vx, vy, playerRichInfo) { + spawnPlayerNode(joinIndex, vx, vy, playerDownsyncInfo) { const self = this; const newPlayerNode = cc.instantiate(self.controlledCharacterPrefab) const playerScriptIns = newPlayerNode.getComponent("ControlledCharacter"); - playerScriptIns.joinIndex = joinIndex; - if (1 == joinIndex) { playerScriptIns.setSpecies("SoldierWaterGhost"); } else if (2 == joinIndex) { playerScriptIns.setSpecies("SoldierFireGhost"); - if (0 == playerRichInfo.dir.dx && 0 == playerRichInfo.dir.dy) { + if (0 == playerDownsyncInfo.dirX && 0 == playerDownsyncInfo.dirY) { playerScriptIns.animComp.node.scaleX = (-1.0); } } @@ -760,16 +761,15 @@ cc.Class({ newPlayerNode.setPosition(cc.v2(wpos[0], wpos[1])); playerScriptIns.mapNode = self.node; - const cpos = self.virtualGridToPlayerColliderPos(vx, vy, playerRichInfo); - const d = playerRichInfo.colliderRadius * 2, + const cpos = self.virtualGridToPlayerColliderPos(vx, vy, playerDownsyncInfo); + const d = playerDownsyncInfo.colliderRadius * 2, x0 = cpos[0], y0 = cpos[1]; let pts = [[0, 0], [d, 0], [d, d], [0, d]]; const newPlayerCollider = self.collisionSys.createPolygon(x0, y0, pts); const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex; - newPlayerCollider.collisionPlayerIndex = parseInt(collisionPlayerIndex); - newPlayerCollider.playerId = parseInt(playerRichInfo.id); + newPlayerCollider.data = playerDownsyncInfo; self.collisionSysMap.set(collisionPlayerIndex, newPlayerCollider); safelyAddChild(self.node, newPlayerNode); @@ -777,9 +777,9 @@ cc.Class({ newPlayerNode.active = true; playerScriptIns.updateCharacterAnim({ - dx: playerRichInfo.dir.dx, - dy: playerRichInfo.dir.dy - }, playerRichInfo, true); + dx: playerDownsyncInfo.dirX, + dy: playerDownsyncInfo.dirY, + }, playerDownsyncInfo, true); return [newPlayerNode, playerScriptIns]; }, @@ -973,8 +973,6 @@ cc.Class({ const dy = (wpos[1] - playerRichInfo.node.y); //const justJiggling = (self.jigglingEps1D >= Math.abs(dx) && self.jigglingEps1D >= Math.abs(dy)); playerRichInfo.node.setPosition(wpos[0], wpos[1]); - playerRichInfo.virtualGridX = immediatePlayerInfo.virtualGridX; - playerRichInfo.virtualGridY = immediatePlayerInfo.virtualGridY; // TODO: check "rdf.players[playerId].characterState" instead, might have to play Atk/Atked anim! if (null != delayedInputFrameForPrevRenderFrame) { const decodedInput = self.ctrl.decodeInput(delayedInputFrameForPrevRenderFrame.inputList[playerRichInfo.joinIndex - 1]); @@ -1003,17 +1001,15 @@ cc.Class({ // TODO: Write unit-test for this function to compare with its backend counter part applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputFrame, currRenderFrame, collisionSys, collisionSysMap) { const self = this; - const nextRenderFramePlayers = {} + const nextRenderFramePlayers = {}; for (let playerId in currRenderFrame.players) { const currPlayerDownsync = currRenderFrame.players[playerId]; nextRenderFramePlayers[playerId] = { id: playerId, virtualGridX: currPlayerDownsync.virtualGridX, virtualGridY: currPlayerDownsync.virtualGridY, - dir: { - dx: currPlayerDownsync.dir.dx, - dy: currPlayerDownsync.dir.dy, - }, + dirX: currPlayerDownsync.dirX, + dirY: currPlayerDownsync.dirY, characterState: currPlayerDownsync.characterState, speed: currPlayerDownsync.speed, battleState: currPlayerDownsync.battleState, @@ -1034,6 +1030,8 @@ cc.Class({ const bulletPushbacks = new Array(self.playerRichInfoArr.length); // Guaranteed determinism regardless of traversal order const effPushbacks = new Array(self.playerRichInfoArr.length); // Guaranteed determinism regardless of traversal order + + // Reset playerCollider position from the "virtual grid position" for (let j in self.playerRichInfoArr) { const joinIndex = parseInt(j) + 1; bulletPushbacks[joinIndex - 1] = [0.0, 0.0]; @@ -1042,17 +1040,17 @@ cc.Class({ const playerId = playerRichInfo.id; const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex; const playerCollider = collisionSysMap.get(collisionPlayerIndex); - const player = currRenderFrame.players[playerId]; + const currPlayerDownsync = currRenderFrame.players[playerId]; - const newVx = player.virtualGridX; - const newVy = player.virtualGridY; + const newVx = currPlayerDownsync.virtualGridX; + const newVy = currPlayerDownsync.virtualGridY; const newCpos = self.virtualGridToPlayerColliderPos(newVx, newVy, self.playerRichInfoArr[joinIndex - 1]); playerCollider.x = newCpos[0]; playerCollider.y = newCpos[1]; } // Check bullet-anything collisions first, because the pushbacks caused by bullets might later be reverted by player-barrier collision - const colliderBullets = new Map(); // Will all be removed at the end of `applyInputFrameDownsyncDynamicsOnSingleRenderFrame` due to the need for being rollback-compatible + const bulletColliders = new Map(); // Will all be removed at the end of `applyInputFrameDownsyncDynamicsOnSingleRenderFrame` due to the need for being rollback-compatible const removedBulletsAtCurrFrame = new Set(); for (let k in currRenderFrame.meleeBullets) { const meleeBullet = currRenderFrame.meleeBullets[k]; @@ -1066,39 +1064,39 @@ cc.Class({ const offenderCollider = collisionSysMap.get(collisionOffenderIndex); const offender = currRenderFrame.players[meleeBullet.offenderPlayerId]; - const xfac = Math.sign(offender.dir.dx), - yfac = 0; // By now, straight Punch offset doesn't respect "y-axis" + let xfac = 1, + yfac = 0; // By now, straight Punch offset doesn't respect "y-axis" + if (0 > offender.dirX) { + xfac = -1; + } const x0 = offenderCollider.x + xfac * meleeBullet.hitboxOffset, y0 = offenderCollider.y + yfac * meleeBullet.hitboxOffset; const pts = [[0, 0], [xfac * meleeBullet.hitboxSize.x, 0], [xfac * meleeBullet.hitboxSize.x, meleeBullet.hitboxSize.y], [0, meleeBullet.hitboxSize.y]]; const newBulletCollider = collisionSys.createPolygon(x0, y0, pts); - newBulletCollider.collisionBulletIndex = collisionBulletIndex; - newBulletCollider.offenderPlayerId = meleeBullet.offenderPlayerId; - newBulletCollider.pushback = meleeBullet.pushback; - newBulletCollider.hitStunFrames = meleeBullet.hitStunFrames; + newBulletCollider.data = meleeBullet; collisionSysMap.set(collisionBulletIndex, newBulletCollider); - colliderBullets.set(collisionBulletIndex, newBulletCollider); - console.log(`A meleeBullet=${JSON.stringify(meleeBullet)} is added to collisionSys at renderFrame.id=${currRenderFrame.id} as start-up frames ended and active frame is not yet ended`); + bulletColliders.set(collisionBulletIndex, newBulletCollider); + // console.log(`A meleeBullet is added to collisionSys at renderFrame.id=${currRenderFrame.id} as start-up frames ended and active frame is not yet ended: ${JSON.stringify(meleeBullet)}`); } } collisionSys.update(); const result1 = collisionSys.createResult(); // Can I reuse a "self.collisionSysResult" object throughout the whole battle? - colliderBullets.forEach((bulletCollider, collisionBulletIndex) => { + bulletColliders.forEach((bulletCollider, collisionBulletIndex) => { const potentials = bulletCollider.potentials(); let shouldRemove = false; for (const potential of potentials) { - if (null != potential.playerId && potential.playerId == bulletCollider.offenderPlayerId) continue; + if (null != potential.data && potential.data.joinIndex == bulletCollider.data.offenderJoinIndex) continue; if (!bulletCollider.collides(potential, result1)) continue; - if (null != potential.playerId) { - const joinIndex = potential.collisionPlayerIndex - self.collisionPlayerIndexPrefix; - bulletPushbacks[joinIndex - 1][0] += result1.overlap_x * bulletCollider.pushback; - bulletPushbacks[joinIndex - 1][1] += result1.overlap_y * bulletCollider.pushback; - const thatAckedPlayerInNextFrame = nextRenderFramePlayers[potential.playerId]; + if (null != potential.data && null !== potential.data.joinIndex) { + const joinIndex = potential.data.joinIndex; + bulletPushbacks[joinIndex - 1][0] += bulletCollider.data.pushback; // Only for straight punch, there's no y-pushback + bulletPushbacks[joinIndex - 1][1] += 0; + const thatAckedPlayerInNextFrame = nextRenderFramePlayers[potential.data.id]; thatAckedPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Atked1[0]; const oldFrameToRecover = thatAckedPlayerInNextFrame.framesToRecover; - thatAckedPlayerInNextFrame.framesToRecover = oldFrameToRecover > bulletCollider.hitStunFrames ? oldFrameToRecover : bulletCollider.hitStunFrames; // In case the hit player is already stun, we take the larger "hitStunFrames" + thatAckedPlayerInNextFrame.framesToRecover = (oldFrameToRecover > bulletCollider.data.hitStunFrames ? oldFrameToRecover : bulletCollider.data.hitStunFrames); // In case the hit player is already stun, we extend it } shouldRemove = true; } @@ -1107,9 +1105,9 @@ cc.Class({ } }); + // [WARNING] Remove bullets from collisionSys ANYWAY for the convenience of rollback for (let k in currRenderFrame.meleeBullets) { const meleeBullet = currRenderFrame.meleeBullets[k]; - // [WARNING] remove from collisionSys ANYWAY for the convenience of rollback const collisionBulletIndex = self.collisionBulletIndexPrefix + meleeBullet.battleLocalId; if (collisionSysMap.has(collisionBulletIndex)) { const bulletCollider = collisionSysMap.get(collisionBulletIndex); @@ -1120,10 +1118,10 @@ cc.Class({ toRet.meleeBullets.push(meleeBullet); } + // Process player inputs if (null != delayedInputFrame) { const delayedInputFrameForPrevRenderFrame = self.getCachedInputFrameDownsyncWithPrediction(self._convertToInputFrameId(currRenderFrame.id - 1, self.inputDelayFrames)); const inputList = delayedInputFrame.inputList; - // Process player inputs for (let j in self.playerRichInfoArr) { const joinIndex = parseInt(j) + 1; effPushbacks[joinIndex - 1] = [0.0, 0.0]; @@ -1131,13 +1129,14 @@ cc.Class({ const playerId = playerRichInfo.id; const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex; const playerCollider = collisionSysMap.get(collisionPlayerIndex); - const player = currRenderFrame.players[playerId]; - if (0 < nextRenderFramePlayers[playerId].framesToRecover) { + const currPlayerDownsync = currRenderFrame.players[playerId]; + const thatPlayerInNextFrame = nextRenderFramePlayers[playerId]; + if (0 < thatPlayerInNextFrame.framesToRecover) { // No need to process inputs for this player, but there might be bullet pushbacks on this player + playerCollider.x += bulletPushbacks[joinIndex - 1][0]; + playerCollider.y += bulletPushbacks[joinIndex - 1][1]; if (0 != bulletPushbacks[joinIndex - 1][0] || 0 != bulletPushbacks[joinIndex - 1][1]) { - playerCollider.x += bulletPushbacks[joinIndex - 1][0]; - playerCollider.y += bulletPushbacks[joinIndex - 1][1]; - console.log(`playerId=${playerId}, joinIndex=${joinIndex} is pushbacked back by ${bulletPushbacks[joinIndex - 1]} by bullet impacts, now its framesToRecover is ${player.framesToRecover}`); + console.log(`playerId=${playerId}, joinIndex=${joinIndex} is pushbacked back by ${bulletPushbacks[joinIndex - 1]} by bullet impacts, now its framesToRecover is ${currPlayerDownsync.framesToRecover}`); } continue; } @@ -1148,33 +1147,32 @@ cc.Class({ const prevBtnALevel = (null == prevDecodedInput ? 0 : prevDecodedInput.btnALevel); if (1 == decodedInput.btnALevel && 0 == prevBtnALevel) { - console.log(`playerId=${playerId} triggered a rising-edge of btnA at renderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}`); - // The online map is not yet ready for bullet shooting! - /* - nextRenderFramePlayers[playerId].framesToRecover = PunchAtkConfig.recoveryFrames; - const punch = window.pb.protos.MeleeBullet.create(PunchAtkConfig); - punch.battleLocalId = self.bulletBattleLocalIdCounter++; - punch.offenderJoinIndex = joinIndex; - punch.offenderPlayerId = playerId; - punch.originatedRenderFrameId = currRenderFrame.id; - toRet.meleeBullets.push(punch); - console.log(`A rising-edge of meleeBullet=${JSON.stringify(punch)} is created at renderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}`); + // console.log(`playerId=${playerId} triggered a rising-edge of btnA at renderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}`); + if (self.bulletTriggerEnabled) { + thatPlayerInNextFrame.framesToRecover = window.PunchAtkConfig.recoveryFrames; + const punch = window.pb.protos.MeleeBullet.create(window.PunchAtkConfig); + punch.battleLocalId = self.bulletBattleLocalIdCounter++; + punch.offenderJoinIndex = joinIndex; + punch.offenderPlayerId = playerId; + punch.originatedRenderFrameId = currRenderFrame.id; + toRet.meleeBullets.push(punch); + console.log(`A rising-edge of meleeBullet is created at renderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}: ${JSON.stringify(punch)}`); - nextRenderFramePlayers[playerId].characterState = window.ATK_CHARACTER_STATE.Atk1[0]; - */ + thatPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Atk1[0]; + } } else if (0 == decodedInput.btnALevel && 1 == prevBtnALevel) { - console.log(`playerId=${playerId} triggered a falling-edge of btnA at renderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}`); + // console.log(`playerId=${playerId} triggered a falling-edge of btnA at renderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}`); } else { // No trigger, process movement inputs if (0 != decodedInput.dx || 0 != decodedInput.dy) { // Update directions and thus would eventually update moving animation accordingly - nextRenderFramePlayers[playerId].dir.dx = decodedInput.dx; - nextRenderFramePlayers[playerId].dir.dy = decodedInput.dy; - nextRenderFramePlayers[playerId].characterState = window.ATK_CHARACTER_STATE.Walking[0]; + thatPlayerInNextFrame.dirX = decodedInput.dx; + thatPlayerInNextFrame.dirY = decodedInput.dy; + thatPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Walking[0]; } else { - nextRenderFramePlayers[playerId].characterState = window.ATK_CHARACTER_STATE.Idle1[0]; + thatPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Idle1[0]; } - const movement = self.virtualGridToWorldPos(decodedInput.dx + player.speed * decodedInput.dx, decodedInput.dy + player.speed * decodedInput.dy); + const movement = self.virtualGridToWorldPos(decodedInput.dx + currPlayerDownsync.speed * decodedInput.dx, decodedInput.dy + currPlayerDownsync.speed * decodedInput.dy); playerCollider.x += movement[0]; playerCollider.y += movement[1]; } @@ -1204,8 +1202,9 @@ cc.Class({ const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex; const playerCollider = collisionSysMap.get(collisionPlayerIndex); const newVpos = self.playerColliderAnchorToVirtualGridPos(playerCollider.x - effPushbacks[joinIndex - 1][0], playerCollider.y - effPushbacks[joinIndex - 1][1], self.playerRichInfoArr[j]); - nextRenderFramePlayers[playerId].virtualGridX = newVpos[0]; - nextRenderFramePlayers[playerId].virtualGridY = newVpos[1]; + const thatPlayerInNextFrame = nextRenderFramePlayers[playerId]; + thatPlayerInNextFrame.virtualGridX = newVpos[0]; + thatPlayerInNextFrame.virtualGridY = newVpos[1]; } } diff --git a/frontend/assets/scripts/OfflineMap.js b/frontend/assets/scripts/OfflineMap.js index c77dd49..7787e4b 100644 --- a/frontend/assets/scripts/OfflineMap.js +++ b/frontend/assets/scripts/OfflineMap.js @@ -3,27 +3,27 @@ i18n.init(window.language); // languageID should be equal to the one we input in const OnlineMap = require('./Map'); -const PunchAtkConfig = { +window.PunchAtkConfig = { // for offender startupFrames: 18, activeFrames: 42, - recoveryFrames: 60, // usually but not always "startupFrames+activeFrames" - recoveryFramesOnBlock: 60, // usually but not always the same as "recoveryFrames" - recoveryFramesOnHit: 60, // usually but not always the same as "recoveryFrames" + recoveryFrames: 61, // usually but not always "startupFrames+activeFrames", I hereby set it to be 1 frame more than the actual animation to avoid critical transition, i.e. when the animation is 1 frame from ending but "rdfPlayer.framesToRecover" is already counted 0 and the player triggers an other same attack, making an effective bullet trigger but no animation is played due to same animName is still playing + recoveryFramesOnBlock: 61, + recoveryFramesOnHit: 61, moveforward: { x: 0, y: 0, }, hitboxOffset: 12.0, // should be about the radius of the PlayerCollider hitboxSize: { - x: 32.0, + x: 45.0, y: 32.0, }, // for defender hitStunFrames: 18, blockStunFrames: 9, - pushback: 11.0, + pushback: 22.0, releaseTriggerType: 1, // 1: rising-edge, 2: falling-edge damage: 5 }; @@ -35,45 +35,6 @@ cc.Class({ console.warn("+++++++ Map onDestroy()"); }, - spawnPlayerNode(joinIndex, vx, vy, playerRichInfo) { - const self = this; - const newPlayerNode = cc.instantiate(self.controlledCharacterPrefab) - const playerScriptIns = newPlayerNode.getComponent("ControlledCharacter"); - if (1 == joinIndex) { - playerScriptIns.setSpecies("SoldierWaterGhost"); - } else if (2 == joinIndex) { - playerScriptIns.setSpecies("SoldierFireGhost"); - playerScriptIns.animComp.node.scaleX = (-1.0); - } - const wpos = self.virtualGridToWorldPos(vx, vy); - - newPlayerNode.setPosition(cc.v2(wpos[0], wpos[1])); - - playerScriptIns.mapNode = self.node; - const cpos = self.virtualGridToPlayerColliderPos(vx, vy, playerRichInfo); - const d = playerRichInfo.colliderRadius * 2, - x0 = cpos[0], - y0 = cpos[1]; - let pts = [[0, 0], [d, 0], [d, d], [0, d]]; - - const newPlayerCollider = self.collisionSys.createPolygon(x0, y0, pts); - const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex; - newPlayerCollider.collisionPlayerIndex = parseInt(collisionPlayerIndex); - newPlayerCollider.playerId = parseInt(playerRichInfo.id); - self.collisionSysMap.set(collisionPlayerIndex, newPlayerCollider); - - safelyAddChild(self.node, newPlayerNode); - setLocalZOrder(newPlayerNode, 5); - - newPlayerNode.active = true; - playerScriptIns.updateCharacterAnim({ - dx: playerRichInfo.dir.dx, - dy: playerRichInfo.dir.dy - }, playerRichInfo, true); - - return [newPlayerNode, playerScriptIns]; - }, - onLoad() { const self = this; window.mapIns = self; @@ -182,10 +143,8 @@ cc.Class({ colliderRadius: 12, characterState: window.ATK_CHARACTER_STATE.Idle1[0], framesToRecover: 0, - dir: { - dx: 0, - dy: 0 - } + dirX: 0, + dirY: 0, }, 11: { id: 11, @@ -196,10 +155,8 @@ cc.Class({ colliderRadius: 12, characterState: window.ATK_CHARACTER_STATE.Idle1[0], framesToRecover: 0, - dir: { - dx: 0, - dy: 0 - } + dirX: 0, + dirY: 0, }, } }; @@ -243,214 +200,4 @@ cc.Class({ } } }, - - // Overriding this function to test experimental dynamics - applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputFrame, currRenderFrame, collisionSys, collisionSysMap) { - const self = this; - const nextRenderFramePlayers = {} - for (let playerId in currRenderFrame.players) { - const currPlayerDownsync = currRenderFrame.players[playerId]; - nextRenderFramePlayers[playerId] = { - id: playerId, - virtualGridX: currPlayerDownsync.virtualGridX, - virtualGridY: currPlayerDownsync.virtualGridY, - dir: { - dx: currPlayerDownsync.dir.dx, - dy: currPlayerDownsync.dir.dy, - }, - characterState: currPlayerDownsync.characterState, - speed: currPlayerDownsync.speed, - battleState: currPlayerDownsync.battleState, - score: currPlayerDownsync.score, - removed: currPlayerDownsync.removed, - joinIndex: currPlayerDownsync.joinIndex, - framesToRecover: (0 < currPlayerDownsync.framesToRecover ? currPlayerDownsync.framesToRecover - 1 : 0), - hp: currPlayerDownsync.hp, - maxHp: currPlayerDownsync.maxHp, - }; - } - - const toRet = { - id: currRenderFrame.id + 1, - players: nextRenderFramePlayers, - meleeBullets: [] - }; - - const bulletPushbacks = new Array(self.playerRichInfoArr.length); // Guaranteed determinism regardless of traversal order - const effPushbacks = new Array(self.playerRichInfoArr.length); // Guaranteed determinism regardless of traversal order - for (let j in self.playerRichInfoArr) { - const joinIndex = parseInt(j) + 1; - bulletPushbacks[joinIndex - 1] = [0.0, 0.0]; - effPushbacks[joinIndex - 1] = [0.0, 0.0]; - const playerRichInfo = self.playerRichInfoArr[j]; - const playerId = playerRichInfo.id; - const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex; - const playerCollider = collisionSysMap.get(collisionPlayerIndex); - const player = currRenderFrame.players[playerId]; - - const newVx = player.virtualGridX; - const newVy = player.virtualGridY; - const newCpos = self.virtualGridToPlayerColliderPos(newVx, newVy, self.playerRichInfoArr[joinIndex - 1]); - playerCollider.x = newCpos[0]; - playerCollider.y = newCpos[1]; - } - - // Check bullet-anything collisions first, because the pushbacks caused by bullets might later be reverted by player-barrier collision - const colliderBullets = new Map(); // Will all be removed at the end of `applyInputFrameDownsyncDynamicsOnSingleRenderFrame` due to the need for being rollback-compatible - const removedBulletsAtCurrFrame = new Set(); - for (let k in currRenderFrame.meleeBullets) { - const meleeBullet = currRenderFrame.meleeBullets[k]; - if ( - meleeBullet.originatedRenderFrameId + meleeBullet.startupFrames <= currRenderFrame.id - && - meleeBullet.originatedRenderFrameId + meleeBullet.startupFrames + meleeBullet.activeFrames > currRenderFrame.id - ) { - const collisionBulletIndex = self.collisionBulletIndexPrefix + meleeBullet.battleLocalId; - const collisionOffenderIndex = self.collisionPlayerIndexPrefix + meleeBullet.offenderJoinIndex; - const offenderCollider = collisionSysMap.get(collisionOffenderIndex); - const offender = currRenderFrame.players[meleeBullet.offenderPlayerId]; - - const xfac = Math.sign(offender.dir.dx), - yfac = 0; // By now, straight Punch offset doesn't respect "y-axis" - const x0 = offenderCollider.x + xfac * meleeBullet.hitboxOffset, - y0 = offenderCollider.y + yfac * meleeBullet.hitboxOffset; - const pts = [[0, 0], [xfac * meleeBullet.hitboxSize.x, 0], [xfac * meleeBullet.hitboxSize.x, meleeBullet.hitboxSize.y], [0, meleeBullet.hitboxSize.y]]; - const newBulletCollider = collisionSys.createPolygon(x0, y0, pts); - newBulletCollider.collisionBulletIndex = collisionBulletIndex; - newBulletCollider.offenderPlayerId = meleeBullet.offenderPlayerId; - newBulletCollider.pushback = meleeBullet.pushback; - newBulletCollider.hitStunFrames = meleeBullet.hitStunFrames; - collisionSysMap.set(collisionBulletIndex, newBulletCollider); - colliderBullets.set(collisionBulletIndex, newBulletCollider); - console.log(`A meleeBullet=${JSON.stringify(meleeBullet)} is added to collisionSys at renderFrame.id=${currRenderFrame.id} as start-up frames ended and active frame is not yet ended`); - } - } - - collisionSys.update(); - const result1 = collisionSys.createResult(); // Can I reuse a "self.collisionSysResult" object throughout the whole battle? - - colliderBullets.forEach((bulletCollider, collisionBulletIndex) => { - const potentials = bulletCollider.potentials(); - let shouldRemove = false; - for (const potential of potentials) { - if (null != potential.playerId && potential.playerId == bulletCollider.offenderPlayerId) continue; - if (!bulletCollider.collides(potential, result1)) continue; - if (null != potential.playerId) { - const joinIndex = potential.collisionPlayerIndex - self.collisionPlayerIndexPrefix; - bulletPushbacks[joinIndex - 1][0] += result1.overlap_x * bulletCollider.pushback; - bulletPushbacks[joinIndex - 1][1] += result1.overlap_y * bulletCollider.pushback; - const thatAckedPlayerInNextFrame = nextRenderFramePlayers[potential.playerId]; - thatAckedPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Atked1[0]; - const oldFrameToRecover = thatAckedPlayerInNextFrame.framesToRecover; - thatAckedPlayerInNextFrame.framesToRecover = oldFrameToRecover > bulletCollider.hitStunFrames ? oldFrameToRecover : bulletCollider.hitStunFrames; // In case the hit player is already stun, we take the larger "hitStunFrames" - } - shouldRemove = true; - } - if (shouldRemove) { - removedBulletsAtCurrFrame.add(collisionBulletIndex); - } - }); - - for (let k in currRenderFrame.meleeBullets) { - const meleeBullet = currRenderFrame.meleeBullets[k]; - // [WARNING] remove from collisionSys ANYWAY for the convenience of rollback - const collisionBulletIndex = self.collisionBulletIndexPrefix + meleeBullet.battleLocalId; - if (collisionSysMap.has(collisionBulletIndex)) { - const bulletCollider = collisionSysMap.get(collisionBulletIndex); - bulletCollider.remove(); - collisionSysMap.delete(collisionBulletIndex); - } - if (removedBulletsAtCurrFrame.has(collisionBulletIndex)) continue; - toRet.meleeBullets.push(meleeBullet); - } - - if (null != delayedInputFrame) { - const delayedInputFrameForPrevRenderFrame = self.getCachedInputFrameDownsyncWithPrediction(self._convertToInputFrameId(currRenderFrame.id - 1, self.inputDelayFrames)); - const inputList = delayedInputFrame.inputList; - // Process player inputs - for (let j in self.playerRichInfoArr) { - const joinIndex = parseInt(j) + 1; - effPushbacks[joinIndex - 1] = [0.0, 0.0]; - const playerRichInfo = self.playerRichInfoArr[j]; - const playerId = playerRichInfo.id; - const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex; - const playerCollider = collisionSysMap.get(collisionPlayerIndex); - const player = currRenderFrame.players[playerId]; - if (0 < nextRenderFramePlayers[playerId].framesToRecover) { - // No need to process inputs for this player, but there might be bullet pushbacks on this player - if (0 != bulletPushbacks[joinIndex - 1][0] || 0 != bulletPushbacks[joinIndex - 1][1]) { - playerCollider.x += bulletPushbacks[joinIndex - 1][0]; - playerCollider.y += bulletPushbacks[joinIndex - 1][1]; - console.log(`playerId=${playerId}, joinIndex=${joinIndex} is pushbacked back by ${bulletPushbacks[joinIndex - 1]} by bullet impacts, now its framesToRecover is ${player.framesToRecover}`); - } - continue; - } - - const decodedInput = self.ctrl.decodeInput(inputList[joinIndex - 1]); - - const prevDecodedInput = (null == delayedInputFrameForPrevRenderFrame ? null : self.ctrl.decodeInput(delayedInputFrameForPrevRenderFrame.inputList[joinIndex - 1])); - const prevBtnALevel = (null == prevDecodedInput ? 0 : prevDecodedInput.btnALevel); - - if (1 == decodedInput.btnALevel && 0 == prevBtnALevel) { - console.log(`playerId=${playerId} triggered a rising-edge of btnA at renderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}`); - nextRenderFramePlayers[playerId].framesToRecover = PunchAtkConfig.recoveryFrames; - const punch = window.pb.protos.MeleeBullet.create(PunchAtkConfig); - punch.battleLocalId = self.bulletBattleLocalIdCounter++; - punch.offenderJoinIndex = joinIndex; - punch.offenderPlayerId = playerId; - punch.originatedRenderFrameId = currRenderFrame.id; - toRet.meleeBullets.push(punch); - console.log(`A rising-edge of meleeBullet=${JSON.stringify(punch)} is created at renderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}`); - - nextRenderFramePlayers[playerId].characterState = window.ATK_CHARACTER_STATE.Atk1[0]; - } else if (0 == decodedInput.btnALevel && 1 == prevBtnALevel) { - console.log(`playerId=${playerId} triggered a falling-edge of btnA at renderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}`); - } else { - // No trigger, process movement inputs - if (0 != decodedInput.dx || 0 != decodedInput.dy) { - // Update directions and thus would eventually update moving animation accordingly - nextRenderFramePlayers[playerId].dir.dx = decodedInput.dx; - nextRenderFramePlayers[playerId].dir.dy = decodedInput.dy; - nextRenderFramePlayers[playerId].characterState = window.ATK_CHARACTER_STATE.Walking[0]; - } else { - nextRenderFramePlayers[playerId].characterState = window.ATK_CHARACTER_STATE.Idle1[0]; - } - const movement = self.virtualGridToWorldPos(decodedInput.dx + player.speed * decodedInput.dx, decodedInput.dy + player.speed * decodedInput.dy); - playerCollider.x += movement[0]; - playerCollider.y += movement[1]; - } - } - - collisionSys.update(); // by now all "bulletCollider"s are removed - const result2 = collisionSys.createResult(); // Can I reuse a "self.collisionSysResult" object throughout the whole battle? - - for (let j in self.playerRichInfoArr) { - const joinIndex = parseInt(j) + 1; - const playerId = self.playerRichInfoArr[j].id; - const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex; - const playerCollider = collisionSysMap.get(collisionPlayerIndex); - const potentials = playerCollider.potentials(); - for (const potential of potentials) { - // Test if the player collides with the wall - if (!playerCollider.collides(potential, result2)) continue; - // Push the player out of the wall - effPushbacks[joinIndex - 1][0] += result2.overlap * result2.overlap_x; - effPushbacks[joinIndex - 1][1] += result2.overlap * result2.overlap_y; - } - } - - for (let j in self.playerRichInfoArr) { - const joinIndex = parseInt(j) + 1; - const playerId = self.playerRichInfoArr[j].id; - const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex; - const playerCollider = collisionSysMap.get(collisionPlayerIndex); - const newVpos = self.playerColliderAnchorToVirtualGridPos(playerCollider.x - effPushbacks[joinIndex - 1][0], playerCollider.y - effPushbacks[joinIndex - 1][1], self.playerRichInfoArr[j]); - nextRenderFramePlayers[playerId].virtualGridX = newVpos[0]; - nextRenderFramePlayers[playerId].virtualGridY = newVpos[1]; - } - - } - - return toRet; - }, }); diff --git a/frontend/assets/scripts/modules/room_downsync_frame_proto_bundle.forcemsg.js b/frontend/assets/scripts/modules/room_downsync_frame_proto_bundle.forcemsg.js index d061163..c42318d 100644 --- a/frontend/assets/scripts/modules/room_downsync_frame_proto_bundle.forcemsg.js +++ b/frontend/assets/scripts/modules/room_downsync_frame_proto_bundle.forcemsg.js @@ -83,9 +83,9 @@ $root.sharedprotos = (function() { Direction.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.dx != null && message.hasOwnProperty("dx")) + if (message.dx != null && Object.hasOwnProperty.call(message, "dx")) writer.uint32(/* id 1, wireType 0 =*/8).int32(message.dx); - if (message.dy != null && message.hasOwnProperty("dy")) + if (message.dy != null && Object.hasOwnProperty.call(message, "dy")) writer.uint32(/* id 2, wireType 0 =*/16).int32(message.dy); return writer; }; @@ -121,12 +121,14 @@ $root.sharedprotos = (function() { while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { - case 1: - message.dx = reader.int32(); - break; - case 2: - message.dy = reader.int32(); - break; + case 1: { + message.dx = reader.int32(); + break; + } + case 2: { + message.dy = reader.int32(); + break; + } default: reader.skipType(tag & 7); break; @@ -225,6 +227,21 @@ $root.sharedprotos = (function() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; + /** + * Gets the default type url for Direction + * @function getTypeUrl + * @memberof sharedprotos.Direction + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + Direction.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/sharedprotos.Direction"; + }; + return Direction; })(); @@ -293,9 +310,9 @@ $root.sharedprotos = (function() { Vec2D.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.x != null && message.hasOwnProperty("x")) + if (message.x != null && Object.hasOwnProperty.call(message, "x")) writer.uint32(/* id 1, wireType 1 =*/9).double(message.x); - if (message.y != null && message.hasOwnProperty("y")) + if (message.y != null && Object.hasOwnProperty.call(message, "y")) writer.uint32(/* id 2, wireType 1 =*/17).double(message.y); return writer; }; @@ -331,12 +348,14 @@ $root.sharedprotos = (function() { while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { - case 1: - message.x = reader.double(); - break; - case 2: - message.y = reader.double(); - break; + case 1: { + message.x = reader.double(); + break; + } + case 2: { + message.y = reader.double(); + break; + } default: reader.skipType(tag & 7); break; @@ -435,6 +454,21 @@ $root.sharedprotos = (function() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; + /** + * Gets the default type url for Vec2D + * @function getTypeUrl + * @memberof sharedprotos.Vec2D + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + Vec2D.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/sharedprotos.Vec2D"; + }; + return Vec2D; })(); @@ -504,7 +538,7 @@ $root.sharedprotos = (function() { Polygon2D.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.anchor != null && message.hasOwnProperty("anchor")) + if (message.anchor != null && Object.hasOwnProperty.call(message, "anchor")) $root.sharedprotos.Vec2D.encode(message.anchor, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); if (message.points != null && message.points.length) for (var i = 0; i < message.points.length; ++i) @@ -543,14 +577,16 @@ $root.sharedprotos = (function() { while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { - case 1: - message.anchor = $root.sharedprotos.Vec2D.decode(reader, reader.uint32()); - break; - case 2: - if (!(message.points && message.points.length)) - message.points = []; - message.points.push($root.sharedprotos.Vec2D.decode(reader, reader.uint32())); - break; + case 1: { + message.anchor = $root.sharedprotos.Vec2D.decode(reader, reader.uint32()); + break; + } + case 2: { + if (!(message.points && message.points.length)) + message.points = []; + message.points.push($root.sharedprotos.Vec2D.decode(reader, reader.uint32())); + break; + } default: reader.skipType(tag & 7); break; @@ -671,6 +707,21 @@ $root.sharedprotos = (function() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; + /** + * Gets the default type url for Polygon2D + * @function getTypeUrl + * @memberof sharedprotos.Polygon2D + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + Polygon2D.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/sharedprotos.Polygon2D"; + }; + return Polygon2D; })(); @@ -768,11 +819,12 @@ $root.sharedprotos = (function() { while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { - case 1: - if (!(message.eles && message.eles.length)) - message.eles = []; - message.eles.push($root.sharedprotos.Vec2D.decode(reader, reader.uint32())); - break; + case 1: { + if (!(message.eles && message.eles.length)) + message.eles = []; + message.eles.push($root.sharedprotos.Vec2D.decode(reader, reader.uint32())); + break; + } default: reader.skipType(tag & 7); break; @@ -879,6 +931,21 @@ $root.sharedprotos = (function() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; + /** + * Gets the default type url for Vec2DList + * @function getTypeUrl + * @memberof sharedprotos.Vec2DList + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + Vec2DList.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/sharedprotos.Vec2DList"; + }; + return Vec2DList; })(); @@ -976,11 +1043,12 @@ $root.sharedprotos = (function() { while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { - case 1: - if (!(message.eles && message.eles.length)) - message.eles = []; - message.eles.push($root.sharedprotos.Polygon2D.decode(reader, reader.uint32())); - break; + case 1: { + if (!(message.eles && message.eles.length)) + message.eles = []; + message.eles.push($root.sharedprotos.Polygon2D.decode(reader, reader.uint32())); + break; + } default: reader.skipType(tag & 7); break; @@ -1087,6 +1155,21 @@ $root.sharedprotos = (function() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; + /** + * Gets the default type url for Polygon2DList + * @function getTypeUrl + * @memberof sharedprotos.Polygon2DList + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + Polygon2DList.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/sharedprotos.Polygon2DList"; + }; + return Polygon2DList; })(); @@ -1367,59 +1450,59 @@ $root.protos = (function() { BattleColliderInfo.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.stageName != null && message.hasOwnProperty("stageName")) + if (message.stageName != null && Object.hasOwnProperty.call(message, "stageName")) writer.uint32(/* id 1, wireType 2 =*/10).string(message.stageName); - if (message.strToVec2DListMap != null && message.hasOwnProperty("strToVec2DListMap")) + if (message.strToVec2DListMap != null && Object.hasOwnProperty.call(message, "strToVec2DListMap")) for (var keys = Object.keys(message.strToVec2DListMap), i = 0; i < keys.length; ++i) { writer.uint32(/* id 2, wireType 2 =*/18).fork().uint32(/* id 1, wireType 2 =*/10).string(keys[i]); $root.sharedprotos.Vec2DList.encode(message.strToVec2DListMap[keys[i]], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim().ldelim(); } - if (message.strToPolygon2DListMap != null && message.hasOwnProperty("strToPolygon2DListMap")) + if (message.strToPolygon2DListMap != null && Object.hasOwnProperty.call(message, "strToPolygon2DListMap")) for (var keys = Object.keys(message.strToPolygon2DListMap), i = 0; i < keys.length; ++i) { writer.uint32(/* id 3, wireType 2 =*/26).fork().uint32(/* id 1, wireType 2 =*/10).string(keys[i]); $root.sharedprotos.Polygon2DList.encode(message.strToPolygon2DListMap[keys[i]], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim().ldelim(); } - if (message.stageDiscreteW != null && message.hasOwnProperty("stageDiscreteW")) + if (message.stageDiscreteW != null && Object.hasOwnProperty.call(message, "stageDiscreteW")) writer.uint32(/* id 4, wireType 0 =*/32).int32(message.stageDiscreteW); - if (message.stageDiscreteH != null && message.hasOwnProperty("stageDiscreteH")) + if (message.stageDiscreteH != null && Object.hasOwnProperty.call(message, "stageDiscreteH")) writer.uint32(/* id 5, wireType 0 =*/40).int32(message.stageDiscreteH); - if (message.stageTileW != null && message.hasOwnProperty("stageTileW")) + if (message.stageTileW != null && Object.hasOwnProperty.call(message, "stageTileW")) writer.uint32(/* id 6, wireType 0 =*/48).int32(message.stageTileW); - if (message.stageTileH != null && message.hasOwnProperty("stageTileH")) + if (message.stageTileH != null && Object.hasOwnProperty.call(message, "stageTileH")) writer.uint32(/* id 7, wireType 0 =*/56).int32(message.stageTileH); - if (message.intervalToPing != null && message.hasOwnProperty("intervalToPing")) + if (message.intervalToPing != null && Object.hasOwnProperty.call(message, "intervalToPing")) writer.uint32(/* id 8, wireType 0 =*/64).int32(message.intervalToPing); - if (message.willKickIfInactiveFor != null && message.hasOwnProperty("willKickIfInactiveFor")) + if (message.willKickIfInactiveFor != null && Object.hasOwnProperty.call(message, "willKickIfInactiveFor")) writer.uint32(/* id 9, wireType 0 =*/72).int32(message.willKickIfInactiveFor); - if (message.boundRoomId != null && message.hasOwnProperty("boundRoomId")) + if (message.boundRoomId != null && Object.hasOwnProperty.call(message, "boundRoomId")) writer.uint32(/* id 10, wireType 0 =*/80).int32(message.boundRoomId); - if (message.battleDurationNanos != null && message.hasOwnProperty("battleDurationNanos")) + if (message.battleDurationNanos != null && Object.hasOwnProperty.call(message, "battleDurationNanos")) writer.uint32(/* id 11, wireType 0 =*/88).int64(message.battleDurationNanos); - if (message.serverFps != null && message.hasOwnProperty("serverFps")) + if (message.serverFps != null && Object.hasOwnProperty.call(message, "serverFps")) writer.uint32(/* id 12, wireType 0 =*/96).int32(message.serverFps); - if (message.inputDelayFrames != null && message.hasOwnProperty("inputDelayFrames")) + if (message.inputDelayFrames != null && Object.hasOwnProperty.call(message, "inputDelayFrames")) writer.uint32(/* id 13, wireType 0 =*/104).int32(message.inputDelayFrames); - if (message.inputScaleFrames != null && message.hasOwnProperty("inputScaleFrames")) + if (message.inputScaleFrames != null && Object.hasOwnProperty.call(message, "inputScaleFrames")) writer.uint32(/* id 14, wireType 0 =*/112).uint32(message.inputScaleFrames); - if (message.nstDelayFrames != null && message.hasOwnProperty("nstDelayFrames")) + if (message.nstDelayFrames != null && Object.hasOwnProperty.call(message, "nstDelayFrames")) writer.uint32(/* id 15, wireType 0 =*/120).int32(message.nstDelayFrames); - if (message.inputFrameUpsyncDelayTolerance != null && message.hasOwnProperty("inputFrameUpsyncDelayTolerance")) + if (message.inputFrameUpsyncDelayTolerance != null && Object.hasOwnProperty.call(message, "inputFrameUpsyncDelayTolerance")) writer.uint32(/* id 16, wireType 0 =*/128).int32(message.inputFrameUpsyncDelayTolerance); - if (message.maxChasingRenderFramesPerUpdate != null && message.hasOwnProperty("maxChasingRenderFramesPerUpdate")) + if (message.maxChasingRenderFramesPerUpdate != null && Object.hasOwnProperty.call(message, "maxChasingRenderFramesPerUpdate")) writer.uint32(/* id 17, wireType 0 =*/136).int32(message.maxChasingRenderFramesPerUpdate); - if (message.playerBattleState != null && message.hasOwnProperty("playerBattleState")) + if (message.playerBattleState != null && Object.hasOwnProperty.call(message, "playerBattleState")) writer.uint32(/* id 18, wireType 0 =*/144).int32(message.playerBattleState); - if (message.rollbackEstimatedDtMillis != null && message.hasOwnProperty("rollbackEstimatedDtMillis")) + if (message.rollbackEstimatedDtMillis != null && Object.hasOwnProperty.call(message, "rollbackEstimatedDtMillis")) writer.uint32(/* id 19, wireType 1 =*/153).double(message.rollbackEstimatedDtMillis); - if (message.rollbackEstimatedDtNanos != null && message.hasOwnProperty("rollbackEstimatedDtNanos")) + if (message.rollbackEstimatedDtNanos != null && Object.hasOwnProperty.call(message, "rollbackEstimatedDtNanos")) writer.uint32(/* id 20, wireType 0 =*/160).int64(message.rollbackEstimatedDtNanos); - if (message.worldToVirtualGridRatio != null && message.hasOwnProperty("worldToVirtualGridRatio")) + if (message.worldToVirtualGridRatio != null && Object.hasOwnProperty.call(message, "worldToVirtualGridRatio")) writer.uint32(/* id 21, wireType 1 =*/169).double(message.worldToVirtualGridRatio); - if (message.virtualGridToWorldRatio != null && message.hasOwnProperty("virtualGridToWorldRatio")) + if (message.virtualGridToWorldRatio != null && Object.hasOwnProperty.call(message, "virtualGridToWorldRatio")) writer.uint32(/* id 22, wireType 1 =*/177).double(message.virtualGridToWorldRatio); - if (message.spAtkLookupFrames != null && message.hasOwnProperty("spAtkLookupFrames")) + if (message.spAtkLookupFrames != null && Object.hasOwnProperty.call(message, "spAtkLookupFrames")) writer.uint32(/* id 23, wireType 0 =*/184).int32(message.spAtkLookupFrames); - if (message.renderCacheSize != null && message.hasOwnProperty("renderCacheSize")) + if (message.renderCacheSize != null && Object.hasOwnProperty.call(message, "renderCacheSize")) writer.uint32(/* id 24, wireType 0 =*/192).int32(message.renderCacheSize); return writer; }; @@ -1451,92 +1534,144 @@ $root.protos = (function() { BattleColliderInfo.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.protos.BattleColliderInfo(), key; + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.protos.BattleColliderInfo(), key, value; while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { - case 1: - message.stageName = reader.string(); - break; - case 2: - reader.skip().pos++; - if (message.strToVec2DListMap === $util.emptyObject) - message.strToVec2DListMap = {}; - key = reader.string(); - reader.pos++; - message.strToVec2DListMap[key] = $root.sharedprotos.Vec2DList.decode(reader, reader.uint32()); - break; - case 3: - reader.skip().pos++; - if (message.strToPolygon2DListMap === $util.emptyObject) - message.strToPolygon2DListMap = {}; - key = reader.string(); - reader.pos++; - message.strToPolygon2DListMap[key] = $root.sharedprotos.Polygon2DList.decode(reader, reader.uint32()); - break; - case 4: - message.stageDiscreteW = reader.int32(); - break; - case 5: - message.stageDiscreteH = reader.int32(); - break; - case 6: - message.stageTileW = reader.int32(); - break; - case 7: - message.stageTileH = reader.int32(); - break; - case 8: - message.intervalToPing = reader.int32(); - break; - case 9: - message.willKickIfInactiveFor = reader.int32(); - break; - case 10: - message.boundRoomId = reader.int32(); - break; - case 11: - message.battleDurationNanos = reader.int64(); - break; - case 12: - message.serverFps = reader.int32(); - break; - case 13: - message.inputDelayFrames = reader.int32(); - break; - case 14: - message.inputScaleFrames = reader.uint32(); - break; - case 15: - message.nstDelayFrames = reader.int32(); - break; - case 16: - message.inputFrameUpsyncDelayTolerance = reader.int32(); - break; - case 17: - message.maxChasingRenderFramesPerUpdate = reader.int32(); - break; - case 18: - message.playerBattleState = reader.int32(); - break; - case 19: - message.rollbackEstimatedDtMillis = reader.double(); - break; - case 20: - message.rollbackEstimatedDtNanos = reader.int64(); - break; - case 21: - message.worldToVirtualGridRatio = reader.double(); - break; - case 22: - message.virtualGridToWorldRatio = reader.double(); - break; - case 23: - message.spAtkLookupFrames = reader.int32(); - break; - case 24: - message.renderCacheSize = reader.int32(); - break; + case 1: { + message.stageName = reader.string(); + break; + } + case 2: { + if (message.strToVec2DListMap === $util.emptyObject) + message.strToVec2DListMap = {}; + var end2 = reader.uint32() + reader.pos; + key = ""; + value = null; + while (reader.pos < end2) { + var tag2 = reader.uint32(); + switch (tag2 >>> 3) { + case 1: + key = reader.string(); + break; + case 2: + value = $root.sharedprotos.Vec2DList.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag2 & 7); + break; + } + } + message.strToVec2DListMap[key] = value; + break; + } + case 3: { + if (message.strToPolygon2DListMap === $util.emptyObject) + message.strToPolygon2DListMap = {}; + var end2 = reader.uint32() + reader.pos; + key = ""; + value = null; + while (reader.pos < end2) { + var tag2 = reader.uint32(); + switch (tag2 >>> 3) { + case 1: + key = reader.string(); + break; + case 2: + value = $root.sharedprotos.Polygon2DList.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag2 & 7); + break; + } + } + message.strToPolygon2DListMap[key] = value; + break; + } + case 4: { + message.stageDiscreteW = reader.int32(); + break; + } + case 5: { + message.stageDiscreteH = reader.int32(); + break; + } + case 6: { + message.stageTileW = reader.int32(); + break; + } + case 7: { + message.stageTileH = reader.int32(); + break; + } + case 8: { + message.intervalToPing = reader.int32(); + break; + } + case 9: { + message.willKickIfInactiveFor = reader.int32(); + break; + } + case 10: { + message.boundRoomId = reader.int32(); + break; + } + case 11: { + message.battleDurationNanos = reader.int64(); + break; + } + case 12: { + message.serverFps = reader.int32(); + break; + } + case 13: { + message.inputDelayFrames = reader.int32(); + break; + } + case 14: { + message.inputScaleFrames = reader.uint32(); + break; + } + case 15: { + message.nstDelayFrames = reader.int32(); + break; + } + case 16: { + message.inputFrameUpsyncDelayTolerance = reader.int32(); + break; + } + case 17: { + message.maxChasingRenderFramesPerUpdate = reader.int32(); + break; + } + case 18: { + message.playerBattleState = reader.int32(); + break; + } + case 19: { + message.rollbackEstimatedDtMillis = reader.double(); + break; + } + case 20: { + message.rollbackEstimatedDtNanos = reader.int64(); + break; + } + case 21: { + message.worldToVirtualGridRatio = reader.double(); + break; + } + case 22: { + message.virtualGridToWorldRatio = reader.double(); + break; + } + case 23: { + message.spAtkLookupFrames = reader.int32(); + break; + } + case 24: { + message.renderCacheSize = reader.int32(); + break; + } default: reader.skipType(tag & 7); break; @@ -1878,6 +2013,21 @@ $root.protos = (function() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; + /** + * Gets the default type url for BattleColliderInfo + * @function getTypeUrl + * @memberof protos.BattleColliderInfo + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + BattleColliderInfo.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/protos.BattleColliderInfo"; + }; + return BattleColliderInfo; })(); @@ -1890,7 +2040,8 @@ $root.protos = (function() { * @property {number|null} [id] PlayerDownsync id * @property {number|null} [virtualGridX] PlayerDownsync virtualGridX * @property {number|null} [virtualGridY] PlayerDownsync virtualGridY - * @property {sharedprotos.Direction|null} [dir] PlayerDownsync dir + * @property {number|null} [dirX] PlayerDownsync dirX + * @property {number|null} [dirY] PlayerDownsync dirY * @property {number|null} [speed] PlayerDownsync speed * @property {number|null} [battleState] PlayerDownsync battleState * @property {number|null} [joinIndex] PlayerDownsync joinIndex @@ -1947,12 +2098,20 @@ $root.protos = (function() { PlayerDownsync.prototype.virtualGridY = 0; /** - * PlayerDownsync dir. - * @member {sharedprotos.Direction|null|undefined} dir + * PlayerDownsync dirX. + * @member {number} dirX * @memberof protos.PlayerDownsync * @instance */ - PlayerDownsync.prototype.dir = null; + PlayerDownsync.prototype.dirX = 0; + + /** + * PlayerDownsync dirY. + * @member {number} dirY + * @memberof protos.PlayerDownsync + * @instance + */ + PlayerDownsync.prototype.dirY = 0; /** * PlayerDownsync speed. @@ -2090,42 +2249,44 @@ $root.protos = (function() { PlayerDownsync.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.id != null && message.hasOwnProperty("id")) + if (message.id != null && Object.hasOwnProperty.call(message, "id")) writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id); - if (message.virtualGridX != null && message.hasOwnProperty("virtualGridX")) + if (message.virtualGridX != null && Object.hasOwnProperty.call(message, "virtualGridX")) writer.uint32(/* id 2, wireType 0 =*/16).int32(message.virtualGridX); - if (message.virtualGridY != null && message.hasOwnProperty("virtualGridY")) + if (message.virtualGridY != null && Object.hasOwnProperty.call(message, "virtualGridY")) writer.uint32(/* id 3, wireType 0 =*/24).int32(message.virtualGridY); - if (message.dir != null && message.hasOwnProperty("dir")) - $root.sharedprotos.Direction.encode(message.dir, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); - if (message.speed != null && message.hasOwnProperty("speed")) - writer.uint32(/* id 5, wireType 0 =*/40).int32(message.speed); - if (message.battleState != null && message.hasOwnProperty("battleState")) - writer.uint32(/* id 6, wireType 0 =*/48).int32(message.battleState); - if (message.joinIndex != null && message.hasOwnProperty("joinIndex")) - writer.uint32(/* id 7, wireType 0 =*/56).int32(message.joinIndex); - if (message.colliderRadius != null && message.hasOwnProperty("colliderRadius")) - writer.uint32(/* id 8, wireType 1 =*/65).double(message.colliderRadius); - if (message.removed != null && message.hasOwnProperty("removed")) - writer.uint32(/* id 9, wireType 0 =*/72).bool(message.removed); - if (message.score != null && message.hasOwnProperty("score")) - writer.uint32(/* id 10, wireType 0 =*/80).int32(message.score); - if (message.lastMoveGmtMillis != null && message.hasOwnProperty("lastMoveGmtMillis")) - writer.uint32(/* id 11, wireType 0 =*/88).int32(message.lastMoveGmtMillis); - if (message.framesToRecover != null && message.hasOwnProperty("framesToRecover")) - writer.uint32(/* id 12, wireType 0 =*/96).int32(message.framesToRecover); - if (message.hp != null && message.hasOwnProperty("hp")) - writer.uint32(/* id 13, wireType 0 =*/104).int32(message.hp); - if (message.maxHp != null && message.hasOwnProperty("maxHp")) - writer.uint32(/* id 14, wireType 0 =*/112).int32(message.maxHp); - if (message.characterState != null && message.hasOwnProperty("characterState")) - writer.uint32(/* id 15, wireType 0 =*/120).int32(message.characterState); - if (message.name != null && message.hasOwnProperty("name")) - writer.uint32(/* id 16, wireType 2 =*/130).string(message.name); - if (message.displayName != null && message.hasOwnProperty("displayName")) - writer.uint32(/* id 17, wireType 2 =*/138).string(message.displayName); - if (message.avatar != null && message.hasOwnProperty("avatar")) - writer.uint32(/* id 18, wireType 2 =*/146).string(message.avatar); + if (message.dirX != null && Object.hasOwnProperty.call(message, "dirX")) + writer.uint32(/* id 4, wireType 0 =*/32).int32(message.dirX); + if (message.dirY != null && Object.hasOwnProperty.call(message, "dirY")) + writer.uint32(/* id 5, wireType 0 =*/40).int32(message.dirY); + if (message.speed != null && Object.hasOwnProperty.call(message, "speed")) + writer.uint32(/* id 6, wireType 0 =*/48).int32(message.speed); + if (message.battleState != null && Object.hasOwnProperty.call(message, "battleState")) + writer.uint32(/* id 7, wireType 0 =*/56).int32(message.battleState); + if (message.joinIndex != null && Object.hasOwnProperty.call(message, "joinIndex")) + writer.uint32(/* id 8, wireType 0 =*/64).int32(message.joinIndex); + if (message.colliderRadius != null && Object.hasOwnProperty.call(message, "colliderRadius")) + writer.uint32(/* id 9, wireType 1 =*/73).double(message.colliderRadius); + if (message.removed != null && Object.hasOwnProperty.call(message, "removed")) + writer.uint32(/* id 10, wireType 0 =*/80).bool(message.removed); + if (message.score != null && Object.hasOwnProperty.call(message, "score")) + writer.uint32(/* id 11, wireType 0 =*/88).int32(message.score); + if (message.lastMoveGmtMillis != null && Object.hasOwnProperty.call(message, "lastMoveGmtMillis")) + writer.uint32(/* id 12, wireType 0 =*/96).int32(message.lastMoveGmtMillis); + if (message.framesToRecover != null && Object.hasOwnProperty.call(message, "framesToRecover")) + writer.uint32(/* id 13, wireType 0 =*/104).int32(message.framesToRecover); + if (message.hp != null && Object.hasOwnProperty.call(message, "hp")) + writer.uint32(/* id 14, wireType 0 =*/112).int32(message.hp); + if (message.maxHp != null && Object.hasOwnProperty.call(message, "maxHp")) + writer.uint32(/* id 15, wireType 0 =*/120).int32(message.maxHp); + if (message.characterState != null && Object.hasOwnProperty.call(message, "characterState")) + writer.uint32(/* id 16, wireType 0 =*/128).int32(message.characterState); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32(/* id 17, wireType 2 =*/138).string(message.name); + if (message.displayName != null && Object.hasOwnProperty.call(message, "displayName")) + writer.uint32(/* id 18, wireType 2 =*/146).string(message.displayName); + if (message.avatar != null && Object.hasOwnProperty.call(message, "avatar")) + writer.uint32(/* id 19, wireType 2 =*/154).string(message.avatar); return writer; }; @@ -2160,60 +2321,82 @@ $root.protos = (function() { while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { - case 1: - message.id = reader.int32(); - break; - case 2: - message.virtualGridX = reader.int32(); - break; - case 3: - message.virtualGridY = reader.int32(); - break; - case 4: - message.dir = $root.sharedprotos.Direction.decode(reader, reader.uint32()); - break; - case 5: - message.speed = reader.int32(); - break; - case 6: - message.battleState = reader.int32(); - break; - case 7: - message.joinIndex = reader.int32(); - break; - case 8: - message.colliderRadius = reader.double(); - break; - case 9: - message.removed = reader.bool(); - break; - case 10: - message.score = reader.int32(); - break; - case 11: - message.lastMoveGmtMillis = reader.int32(); - break; - case 12: - message.framesToRecover = reader.int32(); - break; - case 13: - message.hp = reader.int32(); - break; - case 14: - message.maxHp = reader.int32(); - break; - case 15: - message.characterState = reader.int32(); - break; - case 16: - message.name = reader.string(); - break; - case 17: - message.displayName = reader.string(); - break; - case 18: - message.avatar = reader.string(); - break; + case 1: { + message.id = reader.int32(); + break; + } + case 2: { + message.virtualGridX = reader.int32(); + break; + } + case 3: { + message.virtualGridY = reader.int32(); + break; + } + case 4: { + message.dirX = reader.int32(); + break; + } + case 5: { + message.dirY = reader.int32(); + break; + } + case 6: { + message.speed = reader.int32(); + break; + } + case 7: { + message.battleState = reader.int32(); + break; + } + case 8: { + message.joinIndex = reader.int32(); + break; + } + case 9: { + message.colliderRadius = reader.double(); + break; + } + case 10: { + message.removed = reader.bool(); + break; + } + case 11: { + message.score = reader.int32(); + break; + } + case 12: { + message.lastMoveGmtMillis = reader.int32(); + break; + } + case 13: { + message.framesToRecover = reader.int32(); + break; + } + case 14: { + message.hp = reader.int32(); + break; + } + case 15: { + message.maxHp = reader.int32(); + break; + } + case 16: { + message.characterState = reader.int32(); + break; + } + case 17: { + message.name = reader.string(); + break; + } + case 18: { + message.displayName = reader.string(); + break; + } + case 19: { + message.avatar = reader.string(); + break; + } default: reader.skipType(tag & 7); break; @@ -2258,11 +2441,12 @@ $root.protos = (function() { if (message.virtualGridY != null && message.hasOwnProperty("virtualGridY")) if (!$util.isInteger(message.virtualGridY)) return "virtualGridY: integer expected"; - if (message.dir != null && message.hasOwnProperty("dir")) { - var error = $root.sharedprotos.Direction.verify(message.dir); - if (error) - return "dir." + error; - } + if (message.dirX != null && message.hasOwnProperty("dirX")) + if (!$util.isInteger(message.dirX)) + return "dirX: integer expected"; + if (message.dirY != null && message.hasOwnProperty("dirY")) + if (!$util.isInteger(message.dirY)) + return "dirY: integer expected"; if (message.speed != null && message.hasOwnProperty("speed")) if (!$util.isInteger(message.speed)) return "speed: integer expected"; @@ -2326,11 +2510,10 @@ $root.protos = (function() { message.virtualGridX = object.virtualGridX | 0; if (object.virtualGridY != null) message.virtualGridY = object.virtualGridY | 0; - if (object.dir != null) { - if (typeof object.dir !== "object") - throw TypeError(".protos.PlayerDownsync.dir: object expected"); - message.dir = $root.sharedprotos.Direction.fromObject(object.dir); - } + if (object.dirX != null) + message.dirX = object.dirX | 0; + if (object.dirY != null) + message.dirY = object.dirY | 0; if (object.speed != null) message.speed = object.speed | 0; if (object.battleState != null) @@ -2379,7 +2562,8 @@ $root.protos = (function() { object.id = 0; object.virtualGridX = 0; object.virtualGridY = 0; - object.dir = null; + object.dirX = 0; + object.dirY = 0; object.speed = 0; object.battleState = 0; object.joinIndex = 0; @@ -2401,8 +2585,10 @@ $root.protos = (function() { object.virtualGridX = message.virtualGridX; if (message.virtualGridY != null && message.hasOwnProperty("virtualGridY")) object.virtualGridY = message.virtualGridY; - if (message.dir != null && message.hasOwnProperty("dir")) - object.dir = $root.sharedprotos.Direction.toObject(message.dir, options); + if (message.dirX != null && message.hasOwnProperty("dirX")) + object.dirX = message.dirX; + if (message.dirY != null && message.hasOwnProperty("dirY")) + object.dirY = message.dirY; if (message.speed != null && message.hasOwnProperty("speed")) object.speed = message.speed; if (message.battleState != null && message.hasOwnProperty("battleState")) @@ -2445,6 +2631,21 @@ $root.protos = (function() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; + /** + * Gets the default type url for PlayerDownsync + * @function getTypeUrl + * @memberof protos.PlayerDownsync + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + PlayerDownsync.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/protos.PlayerDownsync"; + }; + return PlayerDownsync; })(); @@ -2522,11 +2723,11 @@ $root.protos = (function() { InputFrameDecoded.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.dx != null && message.hasOwnProperty("dx")) + if (message.dx != null && Object.hasOwnProperty.call(message, "dx")) writer.uint32(/* id 1, wireType 0 =*/8).int32(message.dx); - if (message.dy != null && message.hasOwnProperty("dy")) + if (message.dy != null && Object.hasOwnProperty.call(message, "dy")) writer.uint32(/* id 2, wireType 0 =*/16).int32(message.dy); - if (message.btnALevel != null && message.hasOwnProperty("btnALevel")) + if (message.btnALevel != null && Object.hasOwnProperty.call(message, "btnALevel")) writer.uint32(/* id 3, wireType 0 =*/24).int32(message.btnALevel); return writer; }; @@ -2562,15 +2763,18 @@ $root.protos = (function() { while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { - case 1: - message.dx = reader.int32(); - break; - case 2: - message.dy = reader.int32(); - break; - case 3: - message.btnALevel = reader.int32(); - break; + case 1: { + message.dx = reader.int32(); + break; + } + case 2: { + message.dy = reader.int32(); + break; + } + case 3: { + message.btnALevel = reader.int32(); + break; + } default: reader.skipType(tag & 7); break; @@ -2677,6 +2881,21 @@ $root.protos = (function() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; + /** + * Gets the default type url for InputFrameDecoded + * @function getTypeUrl + * @memberof protos.InputFrameDecoded + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + InputFrameDecoded.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/protos.InputFrameDecoded"; + }; + return InputFrameDecoded; })(); @@ -2745,9 +2964,9 @@ $root.protos = (function() { InputFrameUpsync.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.inputFrameId != null && message.hasOwnProperty("inputFrameId")) + if (message.inputFrameId != null && Object.hasOwnProperty.call(message, "inputFrameId")) writer.uint32(/* id 1, wireType 0 =*/8).int32(message.inputFrameId); - if (message.encoded != null && message.hasOwnProperty("encoded")) + if (message.encoded != null && Object.hasOwnProperty.call(message, "encoded")) writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.encoded); return writer; }; @@ -2783,12 +3002,14 @@ $root.protos = (function() { while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { - case 1: - message.inputFrameId = reader.int32(); - break; - case 2: - message.encoded = reader.uint64(); - break; + case 1: { + message.inputFrameId = reader.int32(); + break; + } + case 2: { + message.encoded = reader.uint64(); + break; + } default: reader.skipType(tag & 7); break; @@ -2901,6 +3122,21 @@ $root.protos = (function() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; + /** + * Gets the default type url for InputFrameUpsync + * @function getTypeUrl + * @memberof protos.InputFrameUpsync + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + InputFrameUpsync.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/protos.InputFrameUpsync"; + }; + return InputFrameUpsync; })(); @@ -2979,7 +3215,7 @@ $root.protos = (function() { InputFrameDownsync.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.inputFrameId != null && message.hasOwnProperty("inputFrameId")) + if (message.inputFrameId != null && Object.hasOwnProperty.call(message, "inputFrameId")) writer.uint32(/* id 1, wireType 0 =*/8).int32(message.inputFrameId); if (message.inputList != null && message.inputList.length) { writer.uint32(/* id 2, wireType 2 =*/18).fork(); @@ -2987,7 +3223,7 @@ $root.protos = (function() { writer.uint64(message.inputList[i]); writer.ldelim(); } - if (message.confirmedList != null && message.hasOwnProperty("confirmedList")) + if (message.confirmedList != null && Object.hasOwnProperty.call(message, "confirmedList")) writer.uint32(/* id 3, wireType 0 =*/24).uint64(message.confirmedList); return writer; }; @@ -3023,22 +3259,25 @@ $root.protos = (function() { while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { - case 1: - message.inputFrameId = reader.int32(); - break; - case 2: - if (!(message.inputList && message.inputList.length)) - message.inputList = []; - if ((tag & 7) === 2) { - var end2 = reader.uint32() + reader.pos; - while (reader.pos < end2) + case 1: { + message.inputFrameId = reader.int32(); + break; + } + case 2: { + if (!(message.inputList && message.inputList.length)) + message.inputList = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.inputList.push(reader.uint64()); + } else message.inputList.push(reader.uint64()); - } else - message.inputList.push(reader.uint64()); - break; - case 3: - message.confirmedList = reader.uint64(); - break; + break; + } + case 3: { + message.confirmedList = reader.uint64(); + break; + } default: reader.skipType(tag & 7); break; @@ -3182,6 +3421,21 @@ $root.protos = (function() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; + /** + * Gets the default type url for InputFrameDownsync + * @function getTypeUrl + * @memberof protos.InputFrameDownsync + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + InputFrameDownsync.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/protos.InputFrameDownsync"; + }; + return InputFrameDownsync; })(); @@ -3241,7 +3495,7 @@ $root.protos = (function() { HeartbeatUpsync.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.clientTimestamp != null && message.hasOwnProperty("clientTimestamp")) + if (message.clientTimestamp != null && Object.hasOwnProperty.call(message, "clientTimestamp")) writer.uint32(/* id 1, wireType 0 =*/8).int64(message.clientTimestamp); return writer; }; @@ -3277,9 +3531,10 @@ $root.protos = (function() { while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { - case 1: - message.clientTimestamp = reader.int64(); - break; + case 1: { + message.clientTimestamp = reader.int64(); + break; + } default: reader.skipType(tag & 7); break; @@ -3383,6 +3638,21 @@ $root.protos = (function() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; + /** + * Gets the default type url for HeartbeatUpsync + * @function getTypeUrl + * @memberof protos.HeartbeatUpsync + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + HeartbeatUpsync.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/protos.HeartbeatUpsync"; + }; + return HeartbeatUpsync; })(); @@ -3506,22 +3776,22 @@ $root.protos = (function() { WsReq.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.msgId != null && message.hasOwnProperty("msgId")) + if (message.msgId != null && Object.hasOwnProperty.call(message, "msgId")) writer.uint32(/* id 1, wireType 0 =*/8).int32(message.msgId); - if (message.playerId != null && message.hasOwnProperty("playerId")) + if (message.playerId != null && Object.hasOwnProperty.call(message, "playerId")) writer.uint32(/* id 2, wireType 0 =*/16).int32(message.playerId); - if (message.act != null && message.hasOwnProperty("act")) + if (message.act != null && Object.hasOwnProperty.call(message, "act")) writer.uint32(/* id 3, wireType 0 =*/24).int32(message.act); - if (message.joinIndex != null && message.hasOwnProperty("joinIndex")) + if (message.joinIndex != null && Object.hasOwnProperty.call(message, "joinIndex")) writer.uint32(/* id 4, wireType 0 =*/32).int32(message.joinIndex); - if (message.ackingFrameId != null && message.hasOwnProperty("ackingFrameId")) + if (message.ackingFrameId != null && Object.hasOwnProperty.call(message, "ackingFrameId")) writer.uint32(/* id 5, wireType 0 =*/40).int32(message.ackingFrameId); - if (message.ackingInputFrameId != null && message.hasOwnProperty("ackingInputFrameId")) + if (message.ackingInputFrameId != null && Object.hasOwnProperty.call(message, "ackingInputFrameId")) writer.uint32(/* id 6, wireType 0 =*/48).int32(message.ackingInputFrameId); if (message.inputFrameUpsyncBatch != null && message.inputFrameUpsyncBatch.length) for (var i = 0; i < message.inputFrameUpsyncBatch.length; ++i) $root.protos.InputFrameUpsync.encode(message.inputFrameUpsyncBatch[i], writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim(); - if (message.hb != null && message.hasOwnProperty("hb")) + if (message.hb != null && Object.hasOwnProperty.call(message, "hb")) $root.protos.HeartbeatUpsync.encode(message.hb, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim(); return writer; }; @@ -3557,32 +3827,40 @@ $root.protos = (function() { while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { - case 1: - message.msgId = reader.int32(); - break; - case 2: - message.playerId = reader.int32(); - break; - case 3: - message.act = reader.int32(); - break; - case 4: - message.joinIndex = reader.int32(); - break; - case 5: - message.ackingFrameId = reader.int32(); - break; - case 6: - message.ackingInputFrameId = reader.int32(); - break; - case 7: - if (!(message.inputFrameUpsyncBatch && message.inputFrameUpsyncBatch.length)) - message.inputFrameUpsyncBatch = []; - message.inputFrameUpsyncBatch.push($root.protos.InputFrameUpsync.decode(reader, reader.uint32())); - break; - case 8: - message.hb = $root.protos.HeartbeatUpsync.decode(reader, reader.uint32()); - break; + case 1: { + message.msgId = reader.int32(); + break; + } + case 2: { + message.playerId = reader.int32(); + break; + } + case 3: { + message.act = reader.int32(); + break; + } + case 4: { + message.joinIndex = reader.int32(); + break; + } + case 5: { + message.ackingFrameId = reader.int32(); + break; + } + case 6: { + message.ackingInputFrameId = reader.int32(); + break; + } + case 7: { + if (!(message.inputFrameUpsyncBatch && message.inputFrameUpsyncBatch.length)) + message.inputFrameUpsyncBatch = []; + message.inputFrameUpsyncBatch.push($root.protos.InputFrameUpsync.decode(reader, reader.uint32())); + break; + } + case 8: { + message.hb = $root.protos.HeartbeatUpsync.decode(reader, reader.uint32()); + break; + } default: reader.skipType(tag & 7); break; @@ -3752,6 +4030,21 @@ $root.protos = (function() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; + /** + * Gets the default type url for WsReq + * @function getTypeUrl + * @memberof protos.WsReq + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + WsReq.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/protos.WsReq"; + }; + return WsReq; })(); @@ -3857,18 +4150,18 @@ $root.protos = (function() { WsResp.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.ret != null && message.hasOwnProperty("ret")) + if (message.ret != null && Object.hasOwnProperty.call(message, "ret")) writer.uint32(/* id 1, wireType 0 =*/8).int32(message.ret); - if (message.echoedMsgId != null && message.hasOwnProperty("echoedMsgId")) + if (message.echoedMsgId != null && Object.hasOwnProperty.call(message, "echoedMsgId")) writer.uint32(/* id 2, wireType 0 =*/16).int32(message.echoedMsgId); - if (message.act != null && message.hasOwnProperty("act")) + if (message.act != null && Object.hasOwnProperty.call(message, "act")) writer.uint32(/* id 3, wireType 0 =*/24).int32(message.act); - if (message.rdf != null && message.hasOwnProperty("rdf")) + if (message.rdf != null && Object.hasOwnProperty.call(message, "rdf")) $root.protos.RoomDownsyncFrame.encode(message.rdf, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); if (message.inputFrameDownsyncBatch != null && message.inputFrameDownsyncBatch.length) for (var i = 0; i < message.inputFrameDownsyncBatch.length; ++i) $root.protos.InputFrameDownsync.encode(message.inputFrameDownsyncBatch[i], writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); - if (message.bciFrame != null && message.hasOwnProperty("bciFrame")) + if (message.bciFrame != null && Object.hasOwnProperty.call(message, "bciFrame")) $root.protos.BattleColliderInfo.encode(message.bciFrame, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); return writer; }; @@ -3904,26 +4197,32 @@ $root.protos = (function() { while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { - case 1: - message.ret = reader.int32(); - break; - case 2: - message.echoedMsgId = reader.int32(); - break; - case 3: - message.act = reader.int32(); - break; - case 4: - message.rdf = $root.protos.RoomDownsyncFrame.decode(reader, reader.uint32()); - break; - case 5: - if (!(message.inputFrameDownsyncBatch && message.inputFrameDownsyncBatch.length)) - message.inputFrameDownsyncBatch = []; - message.inputFrameDownsyncBatch.push($root.protos.InputFrameDownsync.decode(reader, reader.uint32())); - break; - case 6: - message.bciFrame = $root.protos.BattleColliderInfo.decode(reader, reader.uint32()); - break; + case 1: { + message.ret = reader.int32(); + break; + } + case 2: { + message.echoedMsgId = reader.int32(); + break; + } + case 3: { + message.act = reader.int32(); + break; + } + case 4: { + message.rdf = $root.protos.RoomDownsyncFrame.decode(reader, reader.uint32()); + break; + } + case 5: { + if (!(message.inputFrameDownsyncBatch && message.inputFrameDownsyncBatch.length)) + message.inputFrameDownsyncBatch = []; + message.inputFrameDownsyncBatch.push($root.protos.InputFrameDownsync.decode(reader, reader.uint32())); + break; + } + case 6: { + message.bciFrame = $root.protos.BattleColliderInfo.decode(reader, reader.uint32()); + break; + } default: reader.skipType(tag & 7); break; @@ -4082,6 +4381,21 @@ $root.protos = (function() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; + /** + * Gets the default type url for WsResp + * @function getTypeUrl + * @memberof protos.WsResp + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + WsResp.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/protos.WsResp"; + }; + return WsResp; })(); @@ -4285,39 +4599,39 @@ $root.protos = (function() { MeleeBullet.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.battleLocalId != null && message.hasOwnProperty("battleLocalId")) + if (message.battleLocalId != null && Object.hasOwnProperty.call(message, "battleLocalId")) writer.uint32(/* id 1, wireType 0 =*/8).int32(message.battleLocalId); - if (message.startupFrames != null && message.hasOwnProperty("startupFrames")) + if (message.startupFrames != null && Object.hasOwnProperty.call(message, "startupFrames")) writer.uint32(/* id 2, wireType 0 =*/16).int32(message.startupFrames); - if (message.activeFrames != null && message.hasOwnProperty("activeFrames")) + if (message.activeFrames != null && Object.hasOwnProperty.call(message, "activeFrames")) writer.uint32(/* id 3, wireType 0 =*/24).int32(message.activeFrames); - if (message.recoveryFrames != null && message.hasOwnProperty("recoveryFrames")) + if (message.recoveryFrames != null && Object.hasOwnProperty.call(message, "recoveryFrames")) writer.uint32(/* id 4, wireType 0 =*/32).int32(message.recoveryFrames); - if (message.recoveryFramesOnBlock != null && message.hasOwnProperty("recoveryFramesOnBlock")) + if (message.recoveryFramesOnBlock != null && Object.hasOwnProperty.call(message, "recoveryFramesOnBlock")) writer.uint32(/* id 5, wireType 0 =*/40).int32(message.recoveryFramesOnBlock); - if (message.recoveryFramesOnHit != null && message.hasOwnProperty("recoveryFramesOnHit")) + if (message.recoveryFramesOnHit != null && Object.hasOwnProperty.call(message, "recoveryFramesOnHit")) writer.uint32(/* id 6, wireType 0 =*/48).int32(message.recoveryFramesOnHit); - if (message.moveforward != null && message.hasOwnProperty("moveforward")) + if (message.moveforward != null && Object.hasOwnProperty.call(message, "moveforward")) $root.sharedprotos.Vec2D.encode(message.moveforward, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim(); - if (message.hitboxOffset != null && message.hasOwnProperty("hitboxOffset")) + if (message.hitboxOffset != null && Object.hasOwnProperty.call(message, "hitboxOffset")) writer.uint32(/* id 8, wireType 1 =*/65).double(message.hitboxOffset); - if (message.hitboxSize != null && message.hasOwnProperty("hitboxSize")) + if (message.hitboxSize != null && Object.hasOwnProperty.call(message, "hitboxSize")) $root.sharedprotos.Vec2D.encode(message.hitboxSize, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim(); - if (message.originatedRenderFrameId != null && message.hasOwnProperty("originatedRenderFrameId")) + if (message.originatedRenderFrameId != null && Object.hasOwnProperty.call(message, "originatedRenderFrameId")) writer.uint32(/* id 10, wireType 0 =*/80).int32(message.originatedRenderFrameId); - if (message.hitStunFrames != null && message.hasOwnProperty("hitStunFrames")) + if (message.hitStunFrames != null && Object.hasOwnProperty.call(message, "hitStunFrames")) writer.uint32(/* id 11, wireType 0 =*/88).int32(message.hitStunFrames); - if (message.blockStunFrames != null && message.hasOwnProperty("blockStunFrames")) + if (message.blockStunFrames != null && Object.hasOwnProperty.call(message, "blockStunFrames")) writer.uint32(/* id 12, wireType 0 =*/96).int32(message.blockStunFrames); - if (message.pushback != null && message.hasOwnProperty("pushback")) + if (message.pushback != null && Object.hasOwnProperty.call(message, "pushback")) writer.uint32(/* id 13, wireType 1 =*/105).double(message.pushback); - if (message.releaseTriggerType != null && message.hasOwnProperty("releaseTriggerType")) + if (message.releaseTriggerType != null && Object.hasOwnProperty.call(message, "releaseTriggerType")) writer.uint32(/* id 14, wireType 0 =*/112).int32(message.releaseTriggerType); - if (message.damage != null && message.hasOwnProperty("damage")) + if (message.damage != null && Object.hasOwnProperty.call(message, "damage")) writer.uint32(/* id 15, wireType 0 =*/120).int32(message.damage); - if (message.offenderJoinIndex != null && message.hasOwnProperty("offenderJoinIndex")) + if (message.offenderJoinIndex != null && Object.hasOwnProperty.call(message, "offenderJoinIndex")) writer.uint32(/* id 16, wireType 0 =*/128).int32(message.offenderJoinIndex); - if (message.offenderPlayerId != null && message.hasOwnProperty("offenderPlayerId")) + if (message.offenderPlayerId != null && Object.hasOwnProperty.call(message, "offenderPlayerId")) writer.uint32(/* id 17, wireType 0 =*/136).int32(message.offenderPlayerId); return writer; }; @@ -4353,57 +4667,74 @@ $root.protos = (function() { while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { - case 1: - message.battleLocalId = reader.int32(); - break; - case 2: - message.startupFrames = reader.int32(); - break; - case 3: - message.activeFrames = reader.int32(); - break; - case 4: - message.recoveryFrames = reader.int32(); - break; - case 5: - message.recoveryFramesOnBlock = reader.int32(); - break; - case 6: - message.recoveryFramesOnHit = reader.int32(); - break; - case 7: - message.moveforward = $root.sharedprotos.Vec2D.decode(reader, reader.uint32()); - break; - case 8: - message.hitboxOffset = reader.double(); - break; - case 9: - message.hitboxSize = $root.sharedprotos.Vec2D.decode(reader, reader.uint32()); - break; - case 10: - message.originatedRenderFrameId = reader.int32(); - break; - case 11: - message.hitStunFrames = reader.int32(); - break; - case 12: - message.blockStunFrames = reader.int32(); - break; - case 13: - message.pushback = reader.double(); - break; - case 14: - message.releaseTriggerType = reader.int32(); - break; - case 15: - message.damage = reader.int32(); - break; - case 16: - message.offenderJoinIndex = reader.int32(); - break; - case 17: - message.offenderPlayerId = reader.int32(); - break; + case 1: { + message.battleLocalId = reader.int32(); + break; + } + case 2: { + message.startupFrames = reader.int32(); + break; + } + case 3: { + message.activeFrames = reader.int32(); + break; + } + case 4: { + message.recoveryFrames = reader.int32(); + break; + } + case 5: { + message.recoveryFramesOnBlock = reader.int32(); + break; + } + case 6: { + message.recoveryFramesOnHit = reader.int32(); + break; + } + case 7: { + message.moveforward = $root.sharedprotos.Vec2D.decode(reader, reader.uint32()); + break; + } + case 8: { + message.hitboxOffset = reader.double(); + break; + } + case 9: { + message.hitboxSize = $root.sharedprotos.Vec2D.decode(reader, reader.uint32()); + break; + } + case 10: { + message.originatedRenderFrameId = reader.int32(); + break; + } + case 11: { + message.hitStunFrames = reader.int32(); + break; + } + case 12: { + message.blockStunFrames = reader.int32(); + break; + } + case 13: { + message.pushback = reader.double(); + break; + } + case 14: { + message.releaseTriggerType = reader.int32(); + break; + } + case 15: { + message.damage = reader.int32(); + break; + } + case 16: { + message.offenderJoinIndex = reader.int32(); + break; + } + case 17: { + message.offenderPlayerId = reader.int32(); + break; + } default: reader.skipType(tag & 7); break; @@ -4632,6 +4963,21 @@ $root.protos = (function() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; + /** + * Gets the default type url for MeleeBullet + * @function getTypeUrl + * @memberof protos.MeleeBullet + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + MeleeBullet.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/protos.MeleeBullet"; + }; + return MeleeBullet; })(); @@ -4720,14 +5066,14 @@ $root.protos = (function() { RoomDownsyncFrame.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.id != null && message.hasOwnProperty("id")) + if (message.id != null && Object.hasOwnProperty.call(message, "id")) writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id); - if (message.players != null && message.hasOwnProperty("players")) + if (message.players != null && Object.hasOwnProperty.call(message, "players")) for (var keys = Object.keys(message.players), i = 0; i < keys.length; ++i) { writer.uint32(/* id 2, wireType 2 =*/18).fork().uint32(/* id 1, wireType 0 =*/8).int32(keys[i]); $root.protos.PlayerDownsync.encode(message.players[keys[i]], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim().ldelim(); } - if (message.countdownNanos != null && message.hasOwnProperty("countdownNanos")) + if (message.countdownNanos != null && Object.hasOwnProperty.call(message, "countdownNanos")) writer.uint32(/* id 3, wireType 0 =*/24).int64(message.countdownNanos); if (message.meleeBullets != null && message.meleeBullets.length) for (var i = 0; i < message.meleeBullets.length; ++i) @@ -4762,29 +5108,47 @@ $root.protos = (function() { RoomDownsyncFrame.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.protos.RoomDownsyncFrame(), key; + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.protos.RoomDownsyncFrame(), key, value; while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { - case 1: - message.id = reader.int32(); - break; - case 2: - reader.skip().pos++; - if (message.players === $util.emptyObject) - message.players = {}; - key = reader.int32(); - reader.pos++; - message.players[key] = $root.protos.PlayerDownsync.decode(reader, reader.uint32()); - break; - case 3: - message.countdownNanos = reader.int64(); - break; - case 4: - if (!(message.meleeBullets && message.meleeBullets.length)) - message.meleeBullets = []; - message.meleeBullets.push($root.protos.MeleeBullet.decode(reader, reader.uint32())); - break; + case 1: { + message.id = reader.int32(); + break; + } + case 2: { + if (message.players === $util.emptyObject) + message.players = {}; + var end2 = reader.uint32() + reader.pos; + key = 0; + value = null; + while (reader.pos < end2) { + var tag2 = reader.uint32(); + switch (tag2 >>> 3) { + case 1: + key = reader.int32(); + break; + case 2: + value = $root.protos.PlayerDownsync.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag2 & 7); + break; + } + } + message.players[key] = value; + break; + } + case 3: { + message.countdownNanos = reader.int64(); + break; + } + case 4: { + if (!(message.meleeBullets && message.meleeBullets.length)) + message.meleeBullets = []; + message.meleeBullets.push($root.protos.MeleeBullet.decode(reader, reader.uint32())); + break; + } default: reader.skipType(tag & 7); break; @@ -4955,6 +5319,21 @@ $root.protos = (function() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; + /** + * Gets the default type url for RoomDownsyncFrame + * @function getTypeUrl + * @memberof protos.RoomDownsyncFrame + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + RoomDownsyncFrame.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/protos.RoomDownsyncFrame"; + }; + return RoomDownsyncFrame; })();