From 024d527f3dc3726b995f68fa1aa87e286553a38c Mon Sep 17 00:00:00 2001 From: genxium Date: Tue, 22 Nov 2022 17:12:51 +0800 Subject: [PATCH] Drafted attack trigger logic in OfflineMap. --- battle_srv/models/room.go | 8 +- battle_srv/protos/room_downsync_frame.pb.go | 656 +++++--- .../pbfiles/room_downsync_frame.proto | 49 +- frontend/assets/scenes/login.fire | 2 +- frontend/assets/scenes/offline_map_1.fire | 2 +- frontend/assets/scripts/AttackingCharacter.js | 3 + frontend/assets/scripts/Map.js | 19 +- frontend/assets/scripts/OfflineMap.js | 169 ++- ...om_downsync_frame_proto_bundle.forcemsg.js | 1333 +++++++++++++---- 9 files changed, 1707 insertions(+), 534 deletions(-) diff --git a/battle_srv/models/room.go b/battle_srv/models/room.go index 030c5ea..e91ce66 100644 --- a/battle_srv/models/room.go +++ b/battle_srv/models/room.go @@ -266,8 +266,8 @@ func (pR *Room) ChooseStage() error { panic(err) } - // Obtain the content of `gidBoundariesMapInB2World`. - gidBoundariesMapInB2World := make(map[int]StrToPolygon2DListMap, 0) + // Obtain the content of `gidBoundariesMap`. + gidBoundariesMap := make(map[int]StrToPolygon2DListMap, 0) for _, tileset := range pTmxMapIns.Tilesets { relativeTsxFilePath := fmt.Sprintf("%s/%s", filepath.Join(pwd, relativePathForChosenStage), tileset.Source) // Note that "TmxTileset.Source" can be a string of "relative path". absTsxFilePath, err := filepath.Abs(relativeTsxFilePath) @@ -283,10 +283,10 @@ func (pR *Room) ChooseStage() error { panic(err) } - DeserializeTsxToColliderDict(pTmxMapIns, byteArrOfTsxFile, int(tileset.FirstGid), gidBoundariesMapInB2World) + DeserializeTsxToColliderDict(pTmxMapIns, byteArrOfTsxFile, int(tileset.FirstGid), gidBoundariesMap) } - stageDiscreteW, stageDiscreteH, stageTileW, stageTileH, strToVec2DListMap, strToPolygon2DListMap, err := ParseTmxLayersAndGroups(pTmxMapIns, gidBoundariesMapInB2World) + stageDiscreteW, stageDiscreteH, stageTileW, stageTileH, strToVec2DListMap, strToPolygon2DListMap, err := ParseTmxLayersAndGroups(pTmxMapIns, gidBoundariesMap) if nil != err { panic(err) } diff --git a/battle_srv/protos/room_downsync_frame.pb.go b/battle_srv/protos/room_downsync_frame.pb.go index d435a6b..b84ce1b 100644 --- a/battle_srv/protos/room_downsync_frame.pb.go +++ b/battle_srv/protos/room_downsync_frame.pb.go @@ -260,9 +260,13 @@ type PlayerDownsync struct { 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"` - Name string `protobuf:"bytes,12,opt,name=name,proto3" json:"name,omitempty"` - DisplayName string `protobuf:"bytes,13,opt,name=displayName,proto3" json:"displayName,omitempty"` - Avatar string `protobuf:"bytes,14,opt,name=avatar,proto3" json:"avatar,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"` } func (x *PlayerDownsync) Reset() { @@ -374,6 +378,34 @@ func (x *PlayerDownsync) GetLastMoveGmtMillis() int32 { return 0 } +func (x *PlayerDownsync) GetFramesToRecover() int32 { + if x != nil { + return x.FramesToRecover + } + return 0 +} + +func (x *PlayerDownsync) GetHp() int32 { + if x != nil { + return x.Hp + } + return 0 +} + +func (x *PlayerDownsync) GetMaxHp() int32 { + if x != nil { + return x.MaxHp + } + return 0 +} + +func (x *PlayerDownsync) GetCharacterState() int32 { + if x != nil { + return x.CharacterState + } + return 0 +} + func (x *PlayerDownsync) GetName() string { if x != nil { return x.Name @@ -623,69 +655,6 @@ func (x *HeartbeatUpsync) GetClientTimestamp() int64 { return 0 } -type RoomDownsyncFrame struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Players map[int32]*PlayerDownsync `protobuf:"bytes,2,rep,name=players,proto3" json:"players,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - CountdownNanos int64 `protobuf:"varint,3,opt,name=countdownNanos,proto3" json:"countdownNanos,omitempty"` -} - -func (x *RoomDownsyncFrame) Reset() { - *x = RoomDownsyncFrame{} - if protoimpl.UnsafeEnabled { - mi := &file_room_downsync_frame_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RoomDownsyncFrame) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RoomDownsyncFrame) ProtoMessage() {} - -func (x *RoomDownsyncFrame) ProtoReflect() protoreflect.Message { - mi := &file_room_downsync_frame_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RoomDownsyncFrame.ProtoReflect.Descriptor instead. -func (*RoomDownsyncFrame) Descriptor() ([]byte, []int) { - return file_room_downsync_frame_proto_rawDescGZIP(), []int{6} -} - -func (x *RoomDownsyncFrame) GetId() int32 { - if x != nil { - return x.Id - } - return 0 -} - -func (x *RoomDownsyncFrame) GetPlayers() map[int32]*PlayerDownsync { - if x != nil { - return x.Players - } - return nil -} - -func (x *RoomDownsyncFrame) GetCountdownNanos() int64 { - if x != nil { - return x.CountdownNanos - } - return 0 -} - type WsReq struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -704,7 +673,7 @@ type WsReq struct { func (x *WsReq) Reset() { *x = WsReq{} if protoimpl.UnsafeEnabled { - mi := &file_room_downsync_frame_proto_msgTypes[7] + mi := &file_room_downsync_frame_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -717,7 +686,7 @@ func (x *WsReq) String() string { func (*WsReq) ProtoMessage() {} func (x *WsReq) ProtoReflect() protoreflect.Message { - mi := &file_room_downsync_frame_proto_msgTypes[7] + mi := &file_room_downsync_frame_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -730,7 +699,7 @@ func (x *WsReq) ProtoReflect() protoreflect.Message { // Deprecated: Use WsReq.ProtoReflect.Descriptor instead. func (*WsReq) Descriptor() ([]byte, []int) { - return file_room_downsync_frame_proto_rawDescGZIP(), []int{7} + return file_room_downsync_frame_proto_rawDescGZIP(), []int{6} } func (x *WsReq) GetMsgId() int32 { @@ -805,7 +774,7 @@ type WsResp struct { func (x *WsResp) Reset() { *x = WsResp{} if protoimpl.UnsafeEnabled { - mi := &file_room_downsync_frame_proto_msgTypes[8] + mi := &file_room_downsync_frame_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -818,7 +787,7 @@ func (x *WsResp) String() string { func (*WsResp) ProtoMessage() {} func (x *WsResp) ProtoReflect() protoreflect.Message { - mi := &file_room_downsync_frame_proto_msgTypes[8] + mi := &file_room_downsync_frame_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -831,7 +800,7 @@ func (x *WsResp) ProtoReflect() protoreflect.Message { // Deprecated: Use WsResp.ProtoReflect.Descriptor instead. func (*WsResp) Descriptor() ([]byte, []int) { - return file_room_downsync_frame_proto_rawDescGZIP(), []int{8} + return file_room_downsync_frame_proto_rawDescGZIP(), []int{7} } func (x *WsResp) GetRet() int32 { @@ -876,6 +845,246 @@ func (x *WsResp) GetBciFrame() *BattleColliderInfo { return nil } +type MeleeBullet struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // for offender + BattleLocalId int32 `protobuf:"varint,1,opt,name=battleLocalId,proto3" json:"battleLocalId,omitempty"` + StartupFrames int32 `protobuf:"varint,2,opt,name=startupFrames,proto3" json:"startupFrames,omitempty"` + ActiveFrames int32 `protobuf:"varint,3,opt,name=activeFrames,proto3" json:"activeFrames,omitempty"` + RecoveryFrames int32 `protobuf:"varint,4,opt,name=recoveryFrames,proto3" json:"recoveryFrames,omitempty"` + RecoveryFramesOnBlock int32 `protobuf:"varint,5,opt,name=recoveryFramesOnBlock,proto3" json:"recoveryFramesOnBlock,omitempty"` + RecoveryFramesOnHit int32 `protobuf:"varint,6,opt,name=recoveryFramesOnHit,proto3" json:"recoveryFramesOnHit,omitempty"` + Moveforward *sharedprotos.Vec2D `protobuf:"bytes,7,opt,name=moveforward,proto3" json:"moveforward,omitempty"` + HitboxOffset *sharedprotos.Vec2D `protobuf:"bytes,8,opt,name=hitboxOffset,proto3" json:"hitboxOffset,omitempty"` + HitboxSize *sharedprotos.Vec2D `protobuf:"bytes,9,opt,name=hitboxSize,proto3" json:"hitboxSize,omitempty"` + OffenderJoinIndex int32 `protobuf:"varint,10,opt,name=offenderJoinIndex,proto3" json:"offenderJoinIndex,omitempty"` + OriginatedRenderFrameId int32 `protobuf:"varint,11,opt,name=originatedRenderFrameId,proto3" json:"originatedRenderFrameId,omitempty"` + // for defender + HitStunFrames int32 `protobuf:"varint,12,opt,name=hitStunFrames,proto3" json:"hitStunFrames,omitempty"` + BlockStunFrames int32 `protobuf:"varint,13,opt,name=blockStunFrames,proto3" json:"blockStunFrames,omitempty"` + Pushback float64 `protobuf:"fixed64,14,opt,name=pushback,proto3" json:"pushback,omitempty"` + ReleaseTriggerType int32 `protobuf:"varint,15,opt,name=releaseTriggerType,proto3" json:"releaseTriggerType,omitempty"` // 1: rising-edge, 2: falling-edge + Damage int32 `protobuf:"varint,16,opt,name=damage,proto3" json:"damage,omitempty"` +} + +func (x *MeleeBullet) Reset() { + *x = MeleeBullet{} + if protoimpl.UnsafeEnabled { + mi := &file_room_downsync_frame_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MeleeBullet) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MeleeBullet) ProtoMessage() {} + +func (x *MeleeBullet) ProtoReflect() protoreflect.Message { + mi := &file_room_downsync_frame_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MeleeBullet.ProtoReflect.Descriptor instead. +func (*MeleeBullet) Descriptor() ([]byte, []int) { + return file_room_downsync_frame_proto_rawDescGZIP(), []int{8} +} + +func (x *MeleeBullet) GetBattleLocalId() int32 { + if x != nil { + return x.BattleLocalId + } + return 0 +} + +func (x *MeleeBullet) GetStartupFrames() int32 { + if x != nil { + return x.StartupFrames + } + return 0 +} + +func (x *MeleeBullet) GetActiveFrames() int32 { + if x != nil { + return x.ActiveFrames + } + return 0 +} + +func (x *MeleeBullet) GetRecoveryFrames() int32 { + if x != nil { + return x.RecoveryFrames + } + return 0 +} + +func (x *MeleeBullet) GetRecoveryFramesOnBlock() int32 { + if x != nil { + return x.RecoveryFramesOnBlock + } + return 0 +} + +func (x *MeleeBullet) GetRecoveryFramesOnHit() int32 { + if x != nil { + return x.RecoveryFramesOnHit + } + return 0 +} + +func (x *MeleeBullet) GetMoveforward() *sharedprotos.Vec2D { + if x != nil { + return x.Moveforward + } + return nil +} + +func (x *MeleeBullet) GetHitboxOffset() *sharedprotos.Vec2D { + if x != nil { + return x.HitboxOffset + } + return nil +} + +func (x *MeleeBullet) GetHitboxSize() *sharedprotos.Vec2D { + if x != nil { + return x.HitboxSize + } + return nil +} + +func (x *MeleeBullet) GetOffenderJoinIndex() int32 { + if x != nil { + return x.OffenderJoinIndex + } + return 0 +} + +func (x *MeleeBullet) GetOriginatedRenderFrameId() int32 { + if x != nil { + return x.OriginatedRenderFrameId + } + return 0 +} + +func (x *MeleeBullet) GetHitStunFrames() int32 { + if x != nil { + return x.HitStunFrames + } + return 0 +} + +func (x *MeleeBullet) GetBlockStunFrames() int32 { + if x != nil { + return x.BlockStunFrames + } + return 0 +} + +func (x *MeleeBullet) GetPushback() float64 { + if x != nil { + return x.Pushback + } + return 0 +} + +func (x *MeleeBullet) GetReleaseTriggerType() int32 { + if x != nil { + return x.ReleaseTriggerType + } + return 0 +} + +func (x *MeleeBullet) GetDamage() int32 { + if x != nil { + return x.Damage + } + return 0 +} + +type RoomDownsyncFrame struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Players map[int32]*PlayerDownsync `protobuf:"bytes,2,rep,name=players,proto3" json:"players,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + CountdownNanos int64 `protobuf:"varint,3,opt,name=countdownNanos,proto3" json:"countdownNanos,omitempty"` + MeleeBullets []*MeleeBullet `protobuf:"bytes,4,rep,name=meleeBullets,proto3" json:"meleeBullets,omitempty"` // I don't know how to mimic inheritance/composition in protobuf by far, thus using an array for each type of bullet as a compromise +} + +func (x *RoomDownsyncFrame) Reset() { + *x = RoomDownsyncFrame{} + if protoimpl.UnsafeEnabled { + mi := &file_room_downsync_frame_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RoomDownsyncFrame) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RoomDownsyncFrame) ProtoMessage() {} + +func (x *RoomDownsyncFrame) ProtoReflect() protoreflect.Message { + mi := &file_room_downsync_frame_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RoomDownsyncFrame.ProtoReflect.Descriptor instead. +func (*RoomDownsyncFrame) Descriptor() ([]byte, []int) { + return file_room_downsync_frame_proto_rawDescGZIP(), []int{9} +} + +func (x *RoomDownsyncFrame) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *RoomDownsyncFrame) GetPlayers() map[int32]*PlayerDownsync { + if x != nil { + return x.Players + } + return nil +} + +func (x *RoomDownsyncFrame) GetCountdownNanos() int64 { + if x != nil { + return x.CountdownNanos + } + return 0 +} + +func (x *RoomDownsyncFrame) GetMeleeBullets() []*MeleeBullet { + if x != nil { + return x.MeleeBullets + } + return nil +} + var File_room_downsync_frame_proto protoreflect.FileDescriptor var file_room_downsync_frame_proto_rawDesc = []byte{ @@ -970,7 +1179,7 @@ var file_room_downsync_frame_proto_rawDesc = []byte{ 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 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, 0xbd, 0x03, 0x0a, 0x0e, 0x50, 0x6c, 0x61, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb5, 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, @@ -993,34 +1202,123 @@ var file_room_downsync_frame_proto_rawDesc = []byte{ 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, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x0c, 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, 0x0d, 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, 0x0e, 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, 0xe1, 0x01, 0x0a, 0x11, 0x52, 0x6f, 0x6f, + 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, 0xce, 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, 0x37, + 0x0a, 0x0c, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x08, + 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, 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, 0x2c, 0x0a, 0x11, + 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 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, 0x0b, 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, 0x0c, 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, 0x0d, 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, 0x0e, 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, 0x0f, 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, 0x10, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 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, @@ -1029,50 +1327,18 @@ var file_room_downsync_frame_proto_rawDesc = []byte{ 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, 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, 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, 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, + 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 ( @@ -1087,7 +1353,7 @@ func file_room_downsync_frame_proto_rawDescGZIP() []byte { return file_room_downsync_frame_proto_rawDescData } -var file_room_downsync_frame_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_room_downsync_frame_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_room_downsync_frame_proto_goTypes = []interface{}{ (*BattleColliderInfo)(nil), // 0: protos.BattleColliderInfo (*PlayerDownsync)(nil), // 1: protos.PlayerDownsync @@ -1095,34 +1361,40 @@ var file_room_downsync_frame_proto_goTypes = []interface{}{ (*InputFrameUpsync)(nil), // 3: protos.InputFrameUpsync (*InputFrameDownsync)(nil), // 4: protos.InputFrameDownsync (*HeartbeatUpsync)(nil), // 5: protos.HeartbeatUpsync - (*RoomDownsyncFrame)(nil), // 6: protos.RoomDownsyncFrame - (*WsReq)(nil), // 7: protos.WsReq - (*WsResp)(nil), // 8: protos.WsResp - nil, // 9: protos.BattleColliderInfo.StrToVec2DListMapEntry - nil, // 10: protos.BattleColliderInfo.StrToPolygon2DListMapEntry - nil, // 11: protos.RoomDownsyncFrame.PlayersEntry - (*sharedprotos.Direction)(nil), // 12: sharedprotos.Direction - (*sharedprotos.Vec2DList)(nil), // 13: sharedprotos.Vec2DList - (*sharedprotos.Polygon2DList)(nil), // 14: sharedprotos.Polygon2DList + (*WsReq)(nil), // 6: protos.WsReq + (*WsResp)(nil), // 7: protos.WsResp + (*MeleeBullet)(nil), // 8: protos.MeleeBullet + (*RoomDownsyncFrame)(nil), // 9: protos.RoomDownsyncFrame + 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 } var file_room_downsync_frame_proto_depIdxs = []int32{ - 9, // 0: protos.BattleColliderInfo.strToVec2DListMap:type_name -> protos.BattleColliderInfo.StrToVec2DListMapEntry - 10, // 1: protos.BattleColliderInfo.strToPolygon2DListMap:type_name -> protos.BattleColliderInfo.StrToPolygon2DListMapEntry - 12, // 2: protos.PlayerDownsync.dir:type_name -> sharedprotos.Direction - 11, // 3: protos.RoomDownsyncFrame.players:type_name -> protos.RoomDownsyncFrame.PlayersEntry - 3, // 4: protos.WsReq.inputFrameUpsyncBatch:type_name -> protos.InputFrameUpsync - 5, // 5: protos.WsReq.hb:type_name -> protos.HeartbeatUpsync - 6, // 6: protos.WsResp.rdf:type_name -> protos.RoomDownsyncFrame - 4, // 7: protos.WsResp.inputFrameDownsyncBatch:type_name -> protos.InputFrameDownsync - 0, // 8: protos.WsResp.bciFrame:type_name -> protos.BattleColliderInfo - 13, // 9: protos.BattleColliderInfo.StrToVec2DListMapEntry.value:type_name -> sharedprotos.Vec2DList - 14, // 10: protos.BattleColliderInfo.StrToPolygon2DListMapEntry.value:type_name -> sharedprotos.Polygon2DList - 1, // 11: protos.RoomDownsyncFrame.PlayersEntry.value:type_name -> protos.PlayerDownsync - 12, // [12:12] is the sub-list for method output_type - 12, // [12:12] is the sub-list for method input_type - 12, // [12:12] is the sub-list for extension type_name - 12, // [12:12] is the sub-list for extension extendee - 0, // [0:12] is the sub-list for field type_name + 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.hitboxOffset:type_name -> sharedprotos.Vec2D + 14, // 10: protos.MeleeBullet.hitboxSize:type_name -> sharedprotos.Vec2D + 12, // 11: protos.RoomDownsyncFrame.players:type_name -> protos.RoomDownsyncFrame.PlayersEntry + 8, // 12: protos.RoomDownsyncFrame.meleeBullets:type_name -> protos.MeleeBullet + 15, // 13: protos.BattleColliderInfo.StrToVec2DListMapEntry.value:type_name -> sharedprotos.Vec2DList + 16, // 14: protos.BattleColliderInfo.StrToPolygon2DListMapEntry.value:type_name -> sharedprotos.Polygon2DList + 1, // 15: protos.RoomDownsyncFrame.PlayersEntry.value:type_name -> protos.PlayerDownsync + 16, // [16:16] is the sub-list for method output_type + 16, // [16:16] is the sub-list for method input_type + 16, // [16:16] is the sub-list for extension type_name + 16, // [16:16] is the sub-list for extension extendee + 0, // [0:16] is the sub-list for field type_name } func init() { file_room_downsync_frame_proto_init() } @@ -1204,18 +1476,6 @@ func file_room_downsync_frame_proto_init() { } } file_room_downsync_frame_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RoomDownsyncFrame); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_room_downsync_frame_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WsReq); i { case 0: return &v.state @@ -1227,7 +1487,7 @@ func file_room_downsync_frame_proto_init() { return nil } } - file_room_downsync_frame_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_room_downsync_frame_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WsResp); i { case 0: return &v.state @@ -1239,6 +1499,30 @@ func file_room_downsync_frame_proto_init() { return nil } } + file_room_downsync_frame_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MeleeBullet); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_room_downsync_frame_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RoomDownsyncFrame); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -1246,7 +1530,7 @@ func file_room_downsync_frame_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_room_downsync_frame_proto_rawDesc, NumEnums: 0, - NumMessages: 12, + NumMessages: 13, NumExtensions: 0, NumServices: 0, }, diff --git a/frontend/assets/resources/pbfiles/room_downsync_frame.proto b/frontend/assets/resources/pbfiles/room_downsync_frame.proto index b33f9a1..1242f1b 100644 --- a/frontend/assets/resources/pbfiles/room_downsync_frame.proto +++ b/frontend/assets/resources/pbfiles/room_downsync_frame.proto @@ -45,10 +45,14 @@ message PlayerDownsync { bool removed = 9; int32 score = 10; int32 lastMoveGmtMillis = 11; + int32 framesToRecover = 12; + int32 hp = 13; + int32 maxHp = 14; + int32 characterState = 15; - string name = 12; - string displayName = 13; - string avatar = 14; + string name = 16; + string displayName = 17; + string avatar = 18; } message InputFrameDecoded { @@ -72,12 +76,6 @@ message HeartbeatUpsync { int64 clientTimestamp = 1; } -message RoomDownsyncFrame { - int32 id = 1; - map players = 2; - int64 countdownNanos = 3; -} - message WsReq { int32 msgId = 1; int32 playerId = 2; @@ -97,3 +95,36 @@ message WsResp { repeated InputFrameDownsync inputFrameDownsyncBatch = 5; BattleColliderInfo bciFrame = 6; } + +message MeleeBullet { + // Jargon reference https://www.thegamer.com/fighting-games-frame-data-explained/ + // ALL lengths are in world coordinate + + // for offender + int32 battleLocalId = 1; + int32 startupFrames = 2; + int32 activeFrames = 3; + int32 recoveryFrames = 4; + int32 recoveryFramesOnBlock = 5; + int32 recoveryFramesOnHit = 6; + sharedprotos.Vec2D moveforward = 7; + sharedprotos.Vec2D hitboxOffset = 8; + sharedprotos.Vec2D hitboxSize = 9; + int32 offenderJoinIndex = 10; + int32 originatedRenderFrameId = 11; + + // for defender + int32 hitStunFrames = 12; + int32 blockStunFrames = 13; + double pushback = 14; + + int32 releaseTriggerType = 15; // 1: rising-edge, 2: falling-edge + int32 damage = 16; +} + +message RoomDownsyncFrame { + int32 id = 1; + map players = 2; + int64 countdownNanos = 3; + repeated MeleeBullet meleeBullets = 4; // I don't know how to mimic inheritance/composition in protobuf by far, thus using an array for each type of bullet as a compromise +} diff --git a/frontend/assets/scenes/login.fire b/frontend/assets/scenes/login.fire index 5cbb696..76a6bfa 100644 --- a/frontend/assets/scenes/login.fire +++ b/frontend/assets/scenes/login.fire @@ -440,7 +440,7 @@ "array": [ 0, 0, - 210.4441731196186, + 216.50635094610968, 0, 0, 0, diff --git a/frontend/assets/scenes/offline_map_1.fire b/frontend/assets/scenes/offline_map_1.fire index eda2fde..4939b21 100644 --- a/frontend/assets/scenes/offline_map_1.fire +++ b/frontend/assets/scenes/offline_map_1.fire @@ -453,7 +453,7 @@ "array": [ 0, 0, - 210.4441731196186, + 216.50635094610968, 0, 0, 0, diff --git a/frontend/assets/scripts/AttackingCharacter.js b/frontend/assets/scripts/AttackingCharacter.js index df5fefc..9a30f8b 100644 --- a/frontend/assets/scripts/AttackingCharacter.js +++ b/frontend/assets/scripts/AttackingCharacter.js @@ -22,6 +22,9 @@ cc.Class({ ctor() { this.speciesName = null; + this.hp = 100; + this.maxHp = 100; + this.framesToRecover = 0; }, setSpecies(speciesName) { diff --git a/frontend/assets/scripts/Map.js b/frontend/assets/scripts/Map.js index dea1087..8a5e4c3 100644 --- a/frontend/assets/scripts/Map.js +++ b/frontend/assets/scripts/Map.js @@ -300,6 +300,7 @@ cc.Class({ // Clearing previous info of all players. [ENDS] self.renderFrameId = 0; // After battle started + self.bulletBattleLocalIdCounter = 0; self.lastAllConfirmedRenderFrameId = -1; self.lastAllConfirmedInputFrameId = -1; self.lastUpsyncInputFrameId = -1; @@ -313,6 +314,7 @@ cc.Class({ self.collisionSys = new collisions.Collisions(); self.collisionBarrierIndexPrefix = (1 << 16); // For tracking the movements of barriers, though not yet actually used + self.collisionBulletIndexPrefix = (1 << 15); // For tracking the movements of bullets self.collisionSysMap = new Map(); self.transitToState(ALL_MAP_STATES.VISUAL); @@ -408,19 +410,7 @@ cc.Class({ /** Init required prefab ended. */ window.handleBattleColliderInfo = function(parsedBattleColliderInfo) { - self.inputDelayFrames = parsedBattleColliderInfo.inputDelayFrames; - self.inputScaleFrames = parsedBattleColliderInfo.inputScaleFrames; - self.inputFrameUpsyncDelayTolerance = parsedBattleColliderInfo.inputFrameUpsyncDelayTolerance; - - self.battleDurationNanos = parsedBattleColliderInfo.battleDurationNanos; - self.rollbackEstimatedDt = parsedBattleColliderInfo.rollbackEstimatedDt; - self.rollbackEstimatedDtMillis = parsedBattleColliderInfo.rollbackEstimatedDtMillis; - self.rollbackEstimatedDtNanos = parsedBattleColliderInfo.rollbackEstimatedDtNanos; - self.maxChasingRenderFramesPerUpdate = parsedBattleColliderInfo.maxChasingRenderFramesPerUpdate; - self.spAtkLookupFrames = parsedBattleColliderInfo.spAtkLookupFrames; - - self.worldToVirtualGridRatio = parsedBattleColliderInfo.worldToVirtualGridRatio; - self.virtualGridToWorldRatio = parsedBattleColliderInfo.virtualGridToWorldRatio; + Object.assign(self, parsedBattleColliderInfo); const tiledMapIns = self.node.getComponent(cc.TiledMap); @@ -758,7 +748,7 @@ cc.Class({ playerScriptIns.joinIndex = joinIndex; if (1 == joinIndex) { - playerScriptIns.setSpecies("SoldierElf"); + playerScriptIns.setSpecies("SoldierWaterGhost"); } else if (2 == joinIndex) { playerScriptIns.setSpecies("SoldierFireGhost"); if (0 == playerRichInfo.dir.dx && 0 == playerRichInfo.dir.dy) { @@ -1045,7 +1035,6 @@ cc.Class({ const decodedInput = self.ctrl.decodeInput(inputList[joinIndex - 1]); - // console.log(`Got non-zero inputs for playerId=${playerId}, decodedInput=${JSON.stringify(decodedInput)} @currRenderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.id}`); /* Reset "position" of players in "collisionSys" according to "virtual grid position". The easy part is that we don't have path-dependent-integrals to worry about like that of thermal dynamics. */ diff --git a/frontend/assets/scripts/OfflineMap.js b/frontend/assets/scripts/OfflineMap.js index 902213d..a594ca0 100644 --- a/frontend/assets/scripts/OfflineMap.js +++ b/frontend/assets/scripts/OfflineMap.js @@ -3,6 +3,34 @@ i18n.init(window.language); // languageID should be equal to the one we input in const OnlineMap = require('./Map'); +const PunchAtkConfig = { + // for offender + startupFrames: 2, + activeFrames: 2, + recoveryFrames: 4, // usually but not always "startupFrames+activeFrames" + recoveryFramesOnBlock: 4, // usually but not always the same as "recoveryFrames" + recoveryFramesOnHit: 4, // usually but not always the same as "recoveryFrames" + moveforward: { + x: 0, + y: 0, + }, + hitboxOffset: { + x: 24.0, // should be about the radius of the PlayerCollider + y: 0, + }, + hitboxSize: { + x: 24.0, + y: 24.0, + }, + + // for defender + hitStunFrames: 0, + blockStunFrames: 0, + pushback: 10.0, + releaseTriggerType: 1, // 1: rising-edge, 2: falling-edge + damage: 5 +}; + cc.Class({ extends: OnlineMap, @@ -162,8 +190,8 @@ cc.Class({ 11: { id: 11, joinIndex: 2, - virtualGridX: 80*self.worldToVirtualGridRatio, - virtualGridY: 40*self.worldToVirtualGridRatio, + virtualGridX: 80 * self.worldToVirtualGridRatio, + virtualGridY: 40 * self.worldToVirtualGridRatio, speed: 2 * self.worldToVirtualGridRatio, colliderRadius: 12, dir: { @@ -213,4 +241,141 @@ 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, + }, + 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: [] + }; + + if (null != delayedInputFrame) { + const delayedInputFrameForPrevRenderFrame = self.getCachedInputFrameDownsyncWithPrediction(self._convertToInputFrameId(currRenderFrame.id - 1, self.inputDelayFrames)); + const inputList = delayedInputFrame.inputList; + const effPushbacks = new Array(self.playerRichInfoArr.length); // Guaranteed determinism regardless of traversal order + 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]; + + 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}`); + if (0 == player.framesToRecover) { + nextRenderFramePlayers[playerId].framesToRecover = PunchAtkConfig.recoveryFrames; + const punch = window.pb.protos.MeleeBullet.create(PunchAtkConfig); + punch.battleLocalId = self.bulletBattleLocalIdCounter++; + punch.offenderJoinIndex = joinIndex; + 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}`); + } + } 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}`); + } + + /* + Reset "position" of players in "collisionSys" according to "virtual grid position". The easy part is that we don't have path-dependent-integrals to worry about like that of thermal dynamics. + */ + const newVx = player.virtualGridX + (decodedInput.dx + player.speed * decodedInput.dx); + const newVy = player.virtualGridY + (decodedInput.dy + player.speed * decodedInput.dy); + const newCpos = self.virtualGridToPlayerColliderPos(newVx, newVy, self.playerRichInfoArr[joinIndex - 1]); + playerCollider.x = newCpos[0]; + playerCollider.y = newCpos[1]; + 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; + } + } + + for (let k in currRenderFrame.meleeBullets) { + const meleeBullet = currRenderFrame.meleeBullets[k]; + if (meleeBullet.originatedRenderFrameId + meleeBullet.startupFrames + meleeBullet.activeFrames > currRenderFrame.id) { + // Won't cause any collision + const collisionBulletIndex = self.collisionBulletIndexPrefix + meleeBullet.battleLocalId; + const bulletCollider = collisionSysMap.get(collisionBulletIndex); + if (null != bulletCollider) { + console.log(`A rising-edge of meleeBullet=${JSON.stringify(meleeBullet)} is removed from collisionSys at renderFrame.id=${currRenderFrame.id} as active frames ended`); + bulletCollider.remove(); + } + continue; + } + if (meleeBullet.originatedRenderFrameId + meleeBullet.startupFrames == currRenderFrame.id) { + // Add meleeBullet to collisionSys (shall we just remove all bullets at the end of `applyInputFrameDownsyncDynamicsOnSingleRenderFrame` considering that we might be doing the calculation during rollback? + const collisionBulletIndex = self.collisionBulletIndexPrefix + melee.battleLocalId; + const collisionOffenderIndex = self.collisionPlayerIndexPrefix + melee.offenderJoinIndex; + const offenderCollider = collisionSysMap.get(collisionOffenderIndex); + const x0 = offenderCollider.x + meleeBullet.hitboxOffset.x, + y0 = offenderCollider.y + meleeBullet.hitboxOffset.y; + const pts = [[0, 0], [meleeBullet.hitboxSize.x, 0], [meleeBullet.hitboxSize.x, meleeBullet.hitboxSize.y], [0, meleeBullet.hitboxSize.y]]; + const newBulletCollider = collisionSys.createPolygon(x0, y0, pts); + collisionSysMap.set(collisionBulletIndex, newBulletCollider); + console.log(`A rising-edge of meleeBullet=${JSON.stringify(meleeBullet)} is added to collisionSys at renderFrame.id=${currRenderFrame.id} as start-up frames ended`); + } + toRet.meleeBullets.push(meleeBullet); + } + + collisionSys.update(); + const result = 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, result)) continue; + // Push the player out of the wall + effPushbacks[joinIndex - 1][0] += result.overlap * result.overlap_x; + effPushbacks[joinIndex - 1][1] += result.overlap * result.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 6a40721..6eac069 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 @@ -2025,6 +2025,10 @@ $root.protos = (function() { * @property {boolean|null} [removed] PlayerDownsync removed * @property {number|null} [score] PlayerDownsync score * @property {number|null} [lastMoveGmtMillis] PlayerDownsync lastMoveGmtMillis + * @property {number|null} [framesToRecover] PlayerDownsync framesToRecover + * @property {number|null} [hp] PlayerDownsync hp + * @property {number|null} [maxHp] PlayerDownsync maxHp + * @property {number|null} [characterState] PlayerDownsync characterState * @property {string|null} [name] PlayerDownsync name * @property {string|null} [displayName] PlayerDownsync displayName * @property {string|null} [avatar] PlayerDownsync avatar @@ -2133,6 +2137,38 @@ $root.protos = (function() { */ PlayerDownsync.prototype.lastMoveGmtMillis = 0; + /** + * PlayerDownsync framesToRecover. + * @member {number} framesToRecover + * @memberof protos.PlayerDownsync + * @instance + */ + PlayerDownsync.prototype.framesToRecover = 0; + + /** + * PlayerDownsync hp. + * @member {number} hp + * @memberof protos.PlayerDownsync + * @instance + */ + PlayerDownsync.prototype.hp = 0; + + /** + * PlayerDownsync maxHp. + * @member {number} maxHp + * @memberof protos.PlayerDownsync + * @instance + */ + PlayerDownsync.prototype.maxHp = 0; + + /** + * PlayerDownsync characterState. + * @member {number} characterState + * @memberof protos.PlayerDownsync + * @instance + */ + PlayerDownsync.prototype.characterState = 0; + /** * PlayerDownsync name. * @member {string} name @@ -2203,12 +2239,20 @@ $root.protos = (function() { writer.uint32(/* id 10, wireType 0 =*/80).int32(message.score); if (message.lastMoveGmtMillis != null && Object.hasOwnProperty.call(message, "lastMoveGmtMillis")) writer.uint32(/* id 11, wireType 0 =*/88).int32(message.lastMoveGmtMillis); + if (message.framesToRecover != null && Object.hasOwnProperty.call(message, "framesToRecover")) + writer.uint32(/* id 12, wireType 0 =*/96).int32(message.framesToRecover); + if (message.hp != null && Object.hasOwnProperty.call(message, "hp")) + writer.uint32(/* id 13, wireType 0 =*/104).int32(message.hp); + if (message.maxHp != null && Object.hasOwnProperty.call(message, "maxHp")) + writer.uint32(/* id 14, wireType 0 =*/112).int32(message.maxHp); + if (message.characterState != null && Object.hasOwnProperty.call(message, "characterState")) + writer.uint32(/* id 15, wireType 0 =*/120).int32(message.characterState); if (message.name != null && Object.hasOwnProperty.call(message, "name")) - writer.uint32(/* id 12, wireType 2 =*/98).string(message.name); + writer.uint32(/* id 16, wireType 2 =*/130).string(message.name); if (message.displayName != null && Object.hasOwnProperty.call(message, "displayName")) - writer.uint32(/* id 13, wireType 2 =*/106).string(message.displayName); + writer.uint32(/* id 17, wireType 2 =*/138).string(message.displayName); if (message.avatar != null && Object.hasOwnProperty.call(message, "avatar")) - writer.uint32(/* id 14, wireType 2 =*/114).string(message.avatar); + writer.uint32(/* id 18, wireType 2 =*/146).string(message.avatar); return writer; }; @@ -2288,14 +2332,30 @@ $root.protos = (function() { break; } case 12: { - message.name = reader.string(); + message.framesToRecover = reader.int32(); break; } case 13: { - message.displayName = reader.string(); + 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; } @@ -2369,6 +2429,18 @@ $root.protos = (function() { if (message.lastMoveGmtMillis != null && message.hasOwnProperty("lastMoveGmtMillis")) if (!$util.isInteger(message.lastMoveGmtMillis)) return "lastMoveGmtMillis: integer expected"; + if (message.framesToRecover != null && message.hasOwnProperty("framesToRecover")) + if (!$util.isInteger(message.framesToRecover)) + return "framesToRecover: integer expected"; + if (message.hp != null && message.hasOwnProperty("hp")) + if (!$util.isInteger(message.hp)) + return "hp: integer expected"; + if (message.maxHp != null && message.hasOwnProperty("maxHp")) + if (!$util.isInteger(message.maxHp)) + return "maxHp: integer expected"; + if (message.characterState != null && message.hasOwnProperty("characterState")) + if (!$util.isInteger(message.characterState)) + return "characterState: integer expected"; if (message.name != null && message.hasOwnProperty("name")) if (!$util.isString(message.name)) return "name: string expected"; @@ -2418,6 +2490,14 @@ $root.protos = (function() { message.score = object.score | 0; if (object.lastMoveGmtMillis != null) message.lastMoveGmtMillis = object.lastMoveGmtMillis | 0; + if (object.framesToRecover != null) + message.framesToRecover = object.framesToRecover | 0; + if (object.hp != null) + message.hp = object.hp | 0; + if (object.maxHp != null) + message.maxHp = object.maxHp | 0; + if (object.characterState != null) + message.characterState = object.characterState | 0; if (object.name != null) message.name = String(object.name); if (object.displayName != null) @@ -2452,6 +2532,10 @@ $root.protos = (function() { object.removed = false; object.score = 0; object.lastMoveGmtMillis = 0; + object.framesToRecover = 0; + object.hp = 0; + object.maxHp = 0; + object.characterState = 0; object.name = ""; object.displayName = ""; object.avatar = ""; @@ -2478,6 +2562,14 @@ $root.protos = (function() { object.score = message.score; if (message.lastMoveGmtMillis != null && message.hasOwnProperty("lastMoveGmtMillis")) object.lastMoveGmtMillis = message.lastMoveGmtMillis; + if (message.framesToRecover != null && message.hasOwnProperty("framesToRecover")) + object.framesToRecover = message.framesToRecover; + if (message.hp != null && message.hasOwnProperty("hp")) + object.hp = message.hp; + if (message.maxHp != null && message.hasOwnProperty("maxHp")) + object.maxHp = message.maxHp; + if (message.characterState != null && message.hasOwnProperty("characterState")) + object.characterState = message.characterState; if (message.name != null && message.hasOwnProperty("name")) object.name = message.name; if (message.displayName != null && message.hasOwnProperty("displayName")) @@ -3523,317 +3615,6 @@ $root.protos = (function() { return HeartbeatUpsync; })(); - protos.RoomDownsyncFrame = (function() { - - /** - * Properties of a RoomDownsyncFrame. - * @memberof protos - * @interface IRoomDownsyncFrame - * @property {number|null} [id] RoomDownsyncFrame id - * @property {Object.|null} [players] RoomDownsyncFrame players - * @property {number|Long|null} [countdownNanos] RoomDownsyncFrame countdownNanos - */ - - /** - * Constructs a new RoomDownsyncFrame. - * @memberof protos - * @classdesc Represents a RoomDownsyncFrame. - * @implements IRoomDownsyncFrame - * @constructor - * @param {protos.IRoomDownsyncFrame=} [properties] Properties to set - */ - function RoomDownsyncFrame(properties) { - this.players = {}; - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * RoomDownsyncFrame id. - * @member {number} id - * @memberof protos.RoomDownsyncFrame - * @instance - */ - RoomDownsyncFrame.prototype.id = 0; - - /** - * RoomDownsyncFrame players. - * @member {Object.} players - * @memberof protos.RoomDownsyncFrame - * @instance - */ - RoomDownsyncFrame.prototype.players = $util.emptyObject; - - /** - * RoomDownsyncFrame countdownNanos. - * @member {number|Long} countdownNanos - * @memberof protos.RoomDownsyncFrame - * @instance - */ - RoomDownsyncFrame.prototype.countdownNanos = $util.Long ? $util.Long.fromBits(0,0,false) : 0; - - /** - * Creates a new RoomDownsyncFrame instance using the specified properties. - * @function create - * @memberof protos.RoomDownsyncFrame - * @static - * @param {protos.IRoomDownsyncFrame=} [properties] Properties to set - * @returns {protos.RoomDownsyncFrame} RoomDownsyncFrame instance - */ - RoomDownsyncFrame.create = function create(properties) { - return new RoomDownsyncFrame(properties); - }; - - /** - * Encodes the specified RoomDownsyncFrame message. Does not implicitly {@link protos.RoomDownsyncFrame.verify|verify} messages. - * @function encode - * @memberof protos.RoomDownsyncFrame - * @static - * @param {protos.RoomDownsyncFrame} message RoomDownsyncFrame message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - RoomDownsyncFrame.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.id != null && Object.hasOwnProperty.call(message, "id")) - writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id); - 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 && Object.hasOwnProperty.call(message, "countdownNanos")) - writer.uint32(/* id 3, wireType 0 =*/24).int64(message.countdownNanos); - return writer; - }; - - /** - * Encodes the specified RoomDownsyncFrame message, length delimited. Does not implicitly {@link protos.RoomDownsyncFrame.verify|verify} messages. - * @function encodeDelimited - * @memberof protos.RoomDownsyncFrame - * @static - * @param {protos.RoomDownsyncFrame} message RoomDownsyncFrame message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - RoomDownsyncFrame.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a RoomDownsyncFrame message from the specified reader or buffer. - * @function decode - * @memberof protos.RoomDownsyncFrame - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {protos.RoomDownsyncFrame} RoomDownsyncFrame - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - 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, value; - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - 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; - } - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a RoomDownsyncFrame message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof protos.RoomDownsyncFrame - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {protos.RoomDownsyncFrame} RoomDownsyncFrame - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - RoomDownsyncFrame.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a RoomDownsyncFrame message. - * @function verify - * @memberof protos.RoomDownsyncFrame - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - RoomDownsyncFrame.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.id != null && message.hasOwnProperty("id")) - if (!$util.isInteger(message.id)) - return "id: integer expected"; - if (message.players != null && message.hasOwnProperty("players")) { - if (!$util.isObject(message.players)) - return "players: object expected"; - var key = Object.keys(message.players); - for (var i = 0; i < key.length; ++i) { - if (!$util.key32Re.test(key[i])) - return "players: integer key{k:int32} expected"; - { - var error = $root.protos.PlayerDownsync.verify(message.players[key[i]]); - if (error) - return "players." + error; - } - } - } - if (message.countdownNanos != null && message.hasOwnProperty("countdownNanos")) - if (!$util.isInteger(message.countdownNanos) && !(message.countdownNanos && $util.isInteger(message.countdownNanos.low) && $util.isInteger(message.countdownNanos.high))) - return "countdownNanos: integer|Long expected"; - return null; - }; - - /** - * Creates a RoomDownsyncFrame message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof protos.RoomDownsyncFrame - * @static - * @param {Object.} object Plain object - * @returns {protos.RoomDownsyncFrame} RoomDownsyncFrame - */ - RoomDownsyncFrame.fromObject = function fromObject(object) { - if (object instanceof $root.protos.RoomDownsyncFrame) - return object; - var message = new $root.protos.RoomDownsyncFrame(); - if (object.id != null) - message.id = object.id | 0; - if (object.players) { - if (typeof object.players !== "object") - throw TypeError(".protos.RoomDownsyncFrame.players: object expected"); - message.players = {}; - for (var keys = Object.keys(object.players), i = 0; i < keys.length; ++i) { - if (typeof object.players[keys[i]] !== "object") - throw TypeError(".protos.RoomDownsyncFrame.players: object expected"); - message.players[keys[i]] = $root.protos.PlayerDownsync.fromObject(object.players[keys[i]]); - } - } - if (object.countdownNanos != null) - if ($util.Long) - (message.countdownNanos = $util.Long.fromValue(object.countdownNanos)).unsigned = false; - else if (typeof object.countdownNanos === "string") - message.countdownNanos = parseInt(object.countdownNanos, 10); - else if (typeof object.countdownNanos === "number") - message.countdownNanos = object.countdownNanos; - else if (typeof object.countdownNanos === "object") - message.countdownNanos = new $util.LongBits(object.countdownNanos.low >>> 0, object.countdownNanos.high >>> 0).toNumber(); - return message; - }; - - /** - * Creates a plain object from a RoomDownsyncFrame message. Also converts values to other types if specified. - * @function toObject - * @memberof protos.RoomDownsyncFrame - * @static - * @param {protos.RoomDownsyncFrame} message RoomDownsyncFrame - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - RoomDownsyncFrame.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.objects || options.defaults) - object.players = {}; - if (options.defaults) { - object.id = 0; - if ($util.Long) { - var long = new $util.Long(0, 0, false); - object.countdownNanos = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.countdownNanos = options.longs === String ? "0" : 0; - } - if (message.id != null && message.hasOwnProperty("id")) - object.id = message.id; - var keys2; - if (message.players && (keys2 = Object.keys(message.players)).length) { - object.players = {}; - for (var j = 0; j < keys2.length; ++j) - object.players[keys2[j]] = $root.protos.PlayerDownsync.toObject(message.players[keys2[j]], options); - } - if (message.countdownNanos != null && message.hasOwnProperty("countdownNanos")) - if (typeof message.countdownNanos === "number") - object.countdownNanos = options.longs === String ? String(message.countdownNanos) : message.countdownNanos; - else - object.countdownNanos = options.longs === String ? $util.Long.prototype.toString.call(message.countdownNanos) : options.longs === Number ? new $util.LongBits(message.countdownNanos.low >>> 0, message.countdownNanos.high >>> 0).toNumber() : message.countdownNanos; - return object; - }; - - /** - * Converts this RoomDownsyncFrame to JSON. - * @function toJSON - * @memberof protos.RoomDownsyncFrame - * @instance - * @returns {Object.} JSON object - */ - RoomDownsyncFrame.prototype.toJSON = function toJSON() { - 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; - })(); - protos.WsReq = (function() { /** @@ -4577,6 +4358,926 @@ $root.protos = (function() { return WsResp; })(); + protos.MeleeBullet = (function() { + + /** + * Properties of a MeleeBullet. + * @memberof protos + * @interface IMeleeBullet + * @property {number|null} [battleLocalId] MeleeBullet battleLocalId + * @property {number|null} [startupFrames] MeleeBullet startupFrames + * @property {number|null} [activeFrames] MeleeBullet activeFrames + * @property {number|null} [recoveryFrames] MeleeBullet recoveryFrames + * @property {number|null} [recoveryFramesOnBlock] MeleeBullet recoveryFramesOnBlock + * @property {number|null} [recoveryFramesOnHit] MeleeBullet recoveryFramesOnHit + * @property {sharedprotos.Vec2D|null} [moveforward] MeleeBullet moveforward + * @property {sharedprotos.Vec2D|null} [hitboxOffset] MeleeBullet hitboxOffset + * @property {sharedprotos.Vec2D|null} [hitboxSize] MeleeBullet hitboxSize + * @property {number|null} [offenderJoinIndex] MeleeBullet offenderJoinIndex + * @property {number|null} [originatedRenderFrameId] MeleeBullet originatedRenderFrameId + * @property {number|null} [hitStunFrames] MeleeBullet hitStunFrames + * @property {number|null} [blockStunFrames] MeleeBullet blockStunFrames + * @property {number|null} [pushback] MeleeBullet pushback + * @property {number|null} [releaseTriggerType] MeleeBullet releaseTriggerType + * @property {number|null} [damage] MeleeBullet damage + */ + + /** + * Constructs a new MeleeBullet. + * @memberof protos + * @classdesc Represents a MeleeBullet. + * @implements IMeleeBullet + * @constructor + * @param {protos.IMeleeBullet=} [properties] Properties to set + */ + function MeleeBullet(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * MeleeBullet battleLocalId. + * @member {number} battleLocalId + * @memberof protos.MeleeBullet + * @instance + */ + MeleeBullet.prototype.battleLocalId = 0; + + /** + * MeleeBullet startupFrames. + * @member {number} startupFrames + * @memberof protos.MeleeBullet + * @instance + */ + MeleeBullet.prototype.startupFrames = 0; + + /** + * MeleeBullet activeFrames. + * @member {number} activeFrames + * @memberof protos.MeleeBullet + * @instance + */ + MeleeBullet.prototype.activeFrames = 0; + + /** + * MeleeBullet recoveryFrames. + * @member {number} recoveryFrames + * @memberof protos.MeleeBullet + * @instance + */ + MeleeBullet.prototype.recoveryFrames = 0; + + /** + * MeleeBullet recoveryFramesOnBlock. + * @member {number} recoveryFramesOnBlock + * @memberof protos.MeleeBullet + * @instance + */ + MeleeBullet.prototype.recoveryFramesOnBlock = 0; + + /** + * MeleeBullet recoveryFramesOnHit. + * @member {number} recoveryFramesOnHit + * @memberof protos.MeleeBullet + * @instance + */ + MeleeBullet.prototype.recoveryFramesOnHit = 0; + + /** + * MeleeBullet moveforward. + * @member {sharedprotos.Vec2D|null|undefined} moveforward + * @memberof protos.MeleeBullet + * @instance + */ + MeleeBullet.prototype.moveforward = null; + + /** + * MeleeBullet hitboxOffset. + * @member {sharedprotos.Vec2D|null|undefined} hitboxOffset + * @memberof protos.MeleeBullet + * @instance + */ + MeleeBullet.prototype.hitboxOffset = null; + + /** + * MeleeBullet hitboxSize. + * @member {sharedprotos.Vec2D|null|undefined} hitboxSize + * @memberof protos.MeleeBullet + * @instance + */ + MeleeBullet.prototype.hitboxSize = null; + + /** + * MeleeBullet offenderJoinIndex. + * @member {number} offenderJoinIndex + * @memberof protos.MeleeBullet + * @instance + */ + MeleeBullet.prototype.offenderJoinIndex = 0; + + /** + * MeleeBullet originatedRenderFrameId. + * @member {number} originatedRenderFrameId + * @memberof protos.MeleeBullet + * @instance + */ + MeleeBullet.prototype.originatedRenderFrameId = 0; + + /** + * MeleeBullet hitStunFrames. + * @member {number} hitStunFrames + * @memberof protos.MeleeBullet + * @instance + */ + MeleeBullet.prototype.hitStunFrames = 0; + + /** + * MeleeBullet blockStunFrames. + * @member {number} blockStunFrames + * @memberof protos.MeleeBullet + * @instance + */ + MeleeBullet.prototype.blockStunFrames = 0; + + /** + * MeleeBullet pushback. + * @member {number} pushback + * @memberof protos.MeleeBullet + * @instance + */ + MeleeBullet.prototype.pushback = 0; + + /** + * MeleeBullet releaseTriggerType. + * @member {number} releaseTriggerType + * @memberof protos.MeleeBullet + * @instance + */ + MeleeBullet.prototype.releaseTriggerType = 0; + + /** + * MeleeBullet damage. + * @member {number} damage + * @memberof protos.MeleeBullet + * @instance + */ + MeleeBullet.prototype.damage = 0; + + /** + * Creates a new MeleeBullet instance using the specified properties. + * @function create + * @memberof protos.MeleeBullet + * @static + * @param {protos.IMeleeBullet=} [properties] Properties to set + * @returns {protos.MeleeBullet} MeleeBullet instance + */ + MeleeBullet.create = function create(properties) { + return new MeleeBullet(properties); + }; + + /** + * Encodes the specified MeleeBullet message. Does not implicitly {@link protos.MeleeBullet.verify|verify} messages. + * @function encode + * @memberof protos.MeleeBullet + * @static + * @param {protos.MeleeBullet} message MeleeBullet message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MeleeBullet.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.battleLocalId != null && Object.hasOwnProperty.call(message, "battleLocalId")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.battleLocalId); + if (message.startupFrames != null && Object.hasOwnProperty.call(message, "startupFrames")) + writer.uint32(/* id 2, wireType 0 =*/16).int32(message.startupFrames); + if (message.activeFrames != null && Object.hasOwnProperty.call(message, "activeFrames")) + writer.uint32(/* id 3, wireType 0 =*/24).int32(message.activeFrames); + if (message.recoveryFrames != null && Object.hasOwnProperty.call(message, "recoveryFrames")) + writer.uint32(/* id 4, wireType 0 =*/32).int32(message.recoveryFrames); + if (message.recoveryFramesOnBlock != null && Object.hasOwnProperty.call(message, "recoveryFramesOnBlock")) + writer.uint32(/* id 5, wireType 0 =*/40).int32(message.recoveryFramesOnBlock); + if (message.recoveryFramesOnHit != null && Object.hasOwnProperty.call(message, "recoveryFramesOnHit")) + writer.uint32(/* id 6, wireType 0 =*/48).int32(message.recoveryFramesOnHit); + 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 && Object.hasOwnProperty.call(message, "hitboxOffset")) + $root.sharedprotos.Vec2D.encode(message.hitboxOffset, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim(); + 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.offenderJoinIndex != null && Object.hasOwnProperty.call(message, "offenderJoinIndex")) + writer.uint32(/* id 10, wireType 0 =*/80).int32(message.offenderJoinIndex); + if (message.originatedRenderFrameId != null && Object.hasOwnProperty.call(message, "originatedRenderFrameId")) + writer.uint32(/* id 11, wireType 0 =*/88).int32(message.originatedRenderFrameId); + if (message.hitStunFrames != null && Object.hasOwnProperty.call(message, "hitStunFrames")) + writer.uint32(/* id 12, wireType 0 =*/96).int32(message.hitStunFrames); + if (message.blockStunFrames != null && Object.hasOwnProperty.call(message, "blockStunFrames")) + writer.uint32(/* id 13, wireType 0 =*/104).int32(message.blockStunFrames); + if (message.pushback != null && Object.hasOwnProperty.call(message, "pushback")) + writer.uint32(/* id 14, wireType 1 =*/113).double(message.pushback); + if (message.releaseTriggerType != null && Object.hasOwnProperty.call(message, "releaseTriggerType")) + writer.uint32(/* id 15, wireType 0 =*/120).int32(message.releaseTriggerType); + if (message.damage != null && Object.hasOwnProperty.call(message, "damage")) + writer.uint32(/* id 16, wireType 0 =*/128).int32(message.damage); + return writer; + }; + + /** + * Encodes the specified MeleeBullet message, length delimited. Does not implicitly {@link protos.MeleeBullet.verify|verify} messages. + * @function encodeDelimited + * @memberof protos.MeleeBullet + * @static + * @param {protos.MeleeBullet} message MeleeBullet message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MeleeBullet.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MeleeBullet message from the specified reader or buffer. + * @function decode + * @memberof protos.MeleeBullet + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {protos.MeleeBullet} MeleeBullet + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MeleeBullet.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.MeleeBullet(); + 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 = $root.sharedprotos.Vec2D.decode(reader, reader.uint32()); + break; + } + case 9: { + message.hitboxSize = $root.sharedprotos.Vec2D.decode(reader, reader.uint32()); + break; + } + case 10: { + message.offenderJoinIndex = reader.int32(); + break; + } + case 11: { + message.originatedRenderFrameId = reader.int32(); + break; + } + case 12: { + message.hitStunFrames = reader.int32(); + break; + } + case 13: { + message.blockStunFrames = reader.int32(); + break; + } + case 14: { + message.pushback = reader.double(); + break; + } + case 15: { + message.releaseTriggerType = reader.int32(); + break; + } + case 16: { + message.damage = reader.int32(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MeleeBullet message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof protos.MeleeBullet + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {protos.MeleeBullet} MeleeBullet + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MeleeBullet.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MeleeBullet message. + * @function verify + * @memberof protos.MeleeBullet + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MeleeBullet.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.battleLocalId != null && message.hasOwnProperty("battleLocalId")) + if (!$util.isInteger(message.battleLocalId)) + return "battleLocalId: integer expected"; + if (message.startupFrames != null && message.hasOwnProperty("startupFrames")) + if (!$util.isInteger(message.startupFrames)) + return "startupFrames: integer expected"; + if (message.activeFrames != null && message.hasOwnProperty("activeFrames")) + if (!$util.isInteger(message.activeFrames)) + return "activeFrames: integer expected"; + if (message.recoveryFrames != null && message.hasOwnProperty("recoveryFrames")) + if (!$util.isInteger(message.recoveryFrames)) + return "recoveryFrames: integer expected"; + if (message.recoveryFramesOnBlock != null && message.hasOwnProperty("recoveryFramesOnBlock")) + if (!$util.isInteger(message.recoveryFramesOnBlock)) + return "recoveryFramesOnBlock: integer expected"; + if (message.recoveryFramesOnHit != null && message.hasOwnProperty("recoveryFramesOnHit")) + if (!$util.isInteger(message.recoveryFramesOnHit)) + return "recoveryFramesOnHit: integer expected"; + if (message.moveforward != null && message.hasOwnProperty("moveforward")) { + var error = $root.sharedprotos.Vec2D.verify(message.moveforward); + if (error) + return "moveforward." + error; + } + if (message.hitboxOffset != null && message.hasOwnProperty("hitboxOffset")) { + var error = $root.sharedprotos.Vec2D.verify(message.hitboxOffset); + if (error) + return "hitboxOffset." + error; + } + if (message.hitboxSize != null && message.hasOwnProperty("hitboxSize")) { + var error = $root.sharedprotos.Vec2D.verify(message.hitboxSize); + if (error) + return "hitboxSize." + error; + } + if (message.offenderJoinIndex != null && message.hasOwnProperty("offenderJoinIndex")) + if (!$util.isInteger(message.offenderJoinIndex)) + return "offenderJoinIndex: integer expected"; + if (message.originatedRenderFrameId != null && message.hasOwnProperty("originatedRenderFrameId")) + if (!$util.isInteger(message.originatedRenderFrameId)) + return "originatedRenderFrameId: integer expected"; + if (message.hitStunFrames != null && message.hasOwnProperty("hitStunFrames")) + if (!$util.isInteger(message.hitStunFrames)) + return "hitStunFrames: integer expected"; + if (message.blockStunFrames != null && message.hasOwnProperty("blockStunFrames")) + if (!$util.isInteger(message.blockStunFrames)) + return "blockStunFrames: integer expected"; + if (message.pushback != null && message.hasOwnProperty("pushback")) + if (typeof message.pushback !== "number") + return "pushback: number expected"; + if (message.releaseTriggerType != null && message.hasOwnProperty("releaseTriggerType")) + if (!$util.isInteger(message.releaseTriggerType)) + return "releaseTriggerType: integer expected"; + if (message.damage != null && message.hasOwnProperty("damage")) + if (!$util.isInteger(message.damage)) + return "damage: integer expected"; + return null; + }; + + /** + * Creates a MeleeBullet message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof protos.MeleeBullet + * @static + * @param {Object.} object Plain object + * @returns {protos.MeleeBullet} MeleeBullet + */ + MeleeBullet.fromObject = function fromObject(object) { + if (object instanceof $root.protos.MeleeBullet) + return object; + var message = new $root.protos.MeleeBullet(); + if (object.battleLocalId != null) + message.battleLocalId = object.battleLocalId | 0; + if (object.startupFrames != null) + message.startupFrames = object.startupFrames | 0; + if (object.activeFrames != null) + message.activeFrames = object.activeFrames | 0; + if (object.recoveryFrames != null) + message.recoveryFrames = object.recoveryFrames | 0; + if (object.recoveryFramesOnBlock != null) + message.recoveryFramesOnBlock = object.recoveryFramesOnBlock | 0; + if (object.recoveryFramesOnHit != null) + message.recoveryFramesOnHit = object.recoveryFramesOnHit | 0; + if (object.moveforward != null) { + if (typeof object.moveforward !== "object") + throw TypeError(".protos.MeleeBullet.moveforward: object expected"); + message.moveforward = $root.sharedprotos.Vec2D.fromObject(object.moveforward); + } + if (object.hitboxOffset != null) { + if (typeof object.hitboxOffset !== "object") + throw TypeError(".protos.MeleeBullet.hitboxOffset: object expected"); + message.hitboxOffset = $root.sharedprotos.Vec2D.fromObject(object.hitboxOffset); + } + if (object.hitboxSize != null) { + if (typeof object.hitboxSize !== "object") + throw TypeError(".protos.MeleeBullet.hitboxSize: object expected"); + message.hitboxSize = $root.sharedprotos.Vec2D.fromObject(object.hitboxSize); + } + if (object.offenderJoinIndex != null) + message.offenderJoinIndex = object.offenderJoinIndex | 0; + if (object.originatedRenderFrameId != null) + message.originatedRenderFrameId = object.originatedRenderFrameId | 0; + if (object.hitStunFrames != null) + message.hitStunFrames = object.hitStunFrames | 0; + if (object.blockStunFrames != null) + message.blockStunFrames = object.blockStunFrames | 0; + if (object.pushback != null) + message.pushback = Number(object.pushback); + if (object.releaseTriggerType != null) + message.releaseTriggerType = object.releaseTriggerType | 0; + if (object.damage != null) + message.damage = object.damage | 0; + return message; + }; + + /** + * Creates a plain object from a MeleeBullet message. Also converts values to other types if specified. + * @function toObject + * @memberof protos.MeleeBullet + * @static + * @param {protos.MeleeBullet} message MeleeBullet + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + MeleeBullet.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.battleLocalId = 0; + object.startupFrames = 0; + object.activeFrames = 0; + object.recoveryFrames = 0; + object.recoveryFramesOnBlock = 0; + object.recoveryFramesOnHit = 0; + object.moveforward = null; + object.hitboxOffset = null; + object.hitboxSize = null; + object.offenderJoinIndex = 0; + object.originatedRenderFrameId = 0; + object.hitStunFrames = 0; + object.blockStunFrames = 0; + object.pushback = 0; + object.releaseTriggerType = 0; + object.damage = 0; + } + if (message.battleLocalId != null && message.hasOwnProperty("battleLocalId")) + object.battleLocalId = message.battleLocalId; + if (message.startupFrames != null && message.hasOwnProperty("startupFrames")) + object.startupFrames = message.startupFrames; + if (message.activeFrames != null && message.hasOwnProperty("activeFrames")) + object.activeFrames = message.activeFrames; + if (message.recoveryFrames != null && message.hasOwnProperty("recoveryFrames")) + object.recoveryFrames = message.recoveryFrames; + if (message.recoveryFramesOnBlock != null && message.hasOwnProperty("recoveryFramesOnBlock")) + object.recoveryFramesOnBlock = message.recoveryFramesOnBlock; + if (message.recoveryFramesOnHit != null && message.hasOwnProperty("recoveryFramesOnHit")) + object.recoveryFramesOnHit = message.recoveryFramesOnHit; + if (message.moveforward != null && message.hasOwnProperty("moveforward")) + object.moveforward = $root.sharedprotos.Vec2D.toObject(message.moveforward, options); + if (message.hitboxOffset != null && message.hasOwnProperty("hitboxOffset")) + object.hitboxOffset = $root.sharedprotos.Vec2D.toObject(message.hitboxOffset, options); + if (message.hitboxSize != null && message.hasOwnProperty("hitboxSize")) + object.hitboxSize = $root.sharedprotos.Vec2D.toObject(message.hitboxSize, options); + if (message.offenderJoinIndex != null && message.hasOwnProperty("offenderJoinIndex")) + object.offenderJoinIndex = message.offenderJoinIndex; + if (message.originatedRenderFrameId != null && message.hasOwnProperty("originatedRenderFrameId")) + object.originatedRenderFrameId = message.originatedRenderFrameId; + if (message.hitStunFrames != null && message.hasOwnProperty("hitStunFrames")) + object.hitStunFrames = message.hitStunFrames; + if (message.blockStunFrames != null && message.hasOwnProperty("blockStunFrames")) + object.blockStunFrames = message.blockStunFrames; + if (message.pushback != null && message.hasOwnProperty("pushback")) + object.pushback = options.json && !isFinite(message.pushback) ? String(message.pushback) : message.pushback; + if (message.releaseTriggerType != null && message.hasOwnProperty("releaseTriggerType")) + object.releaseTriggerType = message.releaseTriggerType; + if (message.damage != null && message.hasOwnProperty("damage")) + object.damage = message.damage; + return object; + }; + + /** + * Converts this MeleeBullet to JSON. + * @function toJSON + * @memberof protos.MeleeBullet + * @instance + * @returns {Object.} JSON object + */ + MeleeBullet.prototype.toJSON = function toJSON() { + 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; + })(); + + protos.RoomDownsyncFrame = (function() { + + /** + * Properties of a RoomDownsyncFrame. + * @memberof protos + * @interface IRoomDownsyncFrame + * @property {number|null} [id] RoomDownsyncFrame id + * @property {Object.|null} [players] RoomDownsyncFrame players + * @property {number|Long|null} [countdownNanos] RoomDownsyncFrame countdownNanos + * @property {Array.|null} [meleeBullets] RoomDownsyncFrame meleeBullets + */ + + /** + * Constructs a new RoomDownsyncFrame. + * @memberof protos + * @classdesc Represents a RoomDownsyncFrame. + * @implements IRoomDownsyncFrame + * @constructor + * @param {protos.IRoomDownsyncFrame=} [properties] Properties to set + */ + function RoomDownsyncFrame(properties) { + this.players = {}; + this.meleeBullets = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * RoomDownsyncFrame id. + * @member {number} id + * @memberof protos.RoomDownsyncFrame + * @instance + */ + RoomDownsyncFrame.prototype.id = 0; + + /** + * RoomDownsyncFrame players. + * @member {Object.} players + * @memberof protos.RoomDownsyncFrame + * @instance + */ + RoomDownsyncFrame.prototype.players = $util.emptyObject; + + /** + * RoomDownsyncFrame countdownNanos. + * @member {number|Long} countdownNanos + * @memberof protos.RoomDownsyncFrame + * @instance + */ + RoomDownsyncFrame.prototype.countdownNanos = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * RoomDownsyncFrame meleeBullets. + * @member {Array.} meleeBullets + * @memberof protos.RoomDownsyncFrame + * @instance + */ + RoomDownsyncFrame.prototype.meleeBullets = $util.emptyArray; + + /** + * Creates a new RoomDownsyncFrame instance using the specified properties. + * @function create + * @memberof protos.RoomDownsyncFrame + * @static + * @param {protos.IRoomDownsyncFrame=} [properties] Properties to set + * @returns {protos.RoomDownsyncFrame} RoomDownsyncFrame instance + */ + RoomDownsyncFrame.create = function create(properties) { + return new RoomDownsyncFrame(properties); + }; + + /** + * Encodes the specified RoomDownsyncFrame message. Does not implicitly {@link protos.RoomDownsyncFrame.verify|verify} messages. + * @function encode + * @memberof protos.RoomDownsyncFrame + * @static + * @param {protos.RoomDownsyncFrame} message RoomDownsyncFrame message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RoomDownsyncFrame.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.id); + 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 && 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) + $root.protos.MeleeBullet.encode(message.meleeBullets[i], writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified RoomDownsyncFrame message, length delimited. Does not implicitly {@link protos.RoomDownsyncFrame.verify|verify} messages. + * @function encodeDelimited + * @memberof protos.RoomDownsyncFrame + * @static + * @param {protos.RoomDownsyncFrame} message RoomDownsyncFrame message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RoomDownsyncFrame.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a RoomDownsyncFrame message from the specified reader or buffer. + * @function decode + * @memberof protos.RoomDownsyncFrame + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {protos.RoomDownsyncFrame} RoomDownsyncFrame + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + 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, value; + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + 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; + } + } + return message; + }; + + /** + * Decodes a RoomDownsyncFrame message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof protos.RoomDownsyncFrame + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {protos.RoomDownsyncFrame} RoomDownsyncFrame + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RoomDownsyncFrame.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a RoomDownsyncFrame message. + * @function verify + * @memberof protos.RoomDownsyncFrame + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + RoomDownsyncFrame.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isInteger(message.id)) + return "id: integer expected"; + if (message.players != null && message.hasOwnProperty("players")) { + if (!$util.isObject(message.players)) + return "players: object expected"; + var key = Object.keys(message.players); + for (var i = 0; i < key.length; ++i) { + if (!$util.key32Re.test(key[i])) + return "players: integer key{k:int32} expected"; + { + var error = $root.protos.PlayerDownsync.verify(message.players[key[i]]); + if (error) + return "players." + error; + } + } + } + if (message.countdownNanos != null && message.hasOwnProperty("countdownNanos")) + if (!$util.isInteger(message.countdownNanos) && !(message.countdownNanos && $util.isInteger(message.countdownNanos.low) && $util.isInteger(message.countdownNanos.high))) + return "countdownNanos: integer|Long expected"; + if (message.meleeBullets != null && message.hasOwnProperty("meleeBullets")) { + if (!Array.isArray(message.meleeBullets)) + return "meleeBullets: array expected"; + for (var i = 0; i < message.meleeBullets.length; ++i) { + var error = $root.protos.MeleeBullet.verify(message.meleeBullets[i]); + if (error) + return "meleeBullets." + error; + } + } + return null; + }; + + /** + * Creates a RoomDownsyncFrame message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof protos.RoomDownsyncFrame + * @static + * @param {Object.} object Plain object + * @returns {protos.RoomDownsyncFrame} RoomDownsyncFrame + */ + RoomDownsyncFrame.fromObject = function fromObject(object) { + if (object instanceof $root.protos.RoomDownsyncFrame) + return object; + var message = new $root.protos.RoomDownsyncFrame(); + if (object.id != null) + message.id = object.id | 0; + if (object.players) { + if (typeof object.players !== "object") + throw TypeError(".protos.RoomDownsyncFrame.players: object expected"); + message.players = {}; + for (var keys = Object.keys(object.players), i = 0; i < keys.length; ++i) { + if (typeof object.players[keys[i]] !== "object") + throw TypeError(".protos.RoomDownsyncFrame.players: object expected"); + message.players[keys[i]] = $root.protos.PlayerDownsync.fromObject(object.players[keys[i]]); + } + } + if (object.countdownNanos != null) + if ($util.Long) + (message.countdownNanos = $util.Long.fromValue(object.countdownNanos)).unsigned = false; + else if (typeof object.countdownNanos === "string") + message.countdownNanos = parseInt(object.countdownNanos, 10); + else if (typeof object.countdownNanos === "number") + message.countdownNanos = object.countdownNanos; + else if (typeof object.countdownNanos === "object") + message.countdownNanos = new $util.LongBits(object.countdownNanos.low >>> 0, object.countdownNanos.high >>> 0).toNumber(); + if (object.meleeBullets) { + if (!Array.isArray(object.meleeBullets)) + throw TypeError(".protos.RoomDownsyncFrame.meleeBullets: array expected"); + message.meleeBullets = []; + for (var i = 0; i < object.meleeBullets.length; ++i) { + if (typeof object.meleeBullets[i] !== "object") + throw TypeError(".protos.RoomDownsyncFrame.meleeBullets: object expected"); + message.meleeBullets[i] = $root.protos.MeleeBullet.fromObject(object.meleeBullets[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a RoomDownsyncFrame message. Also converts values to other types if specified. + * @function toObject + * @memberof protos.RoomDownsyncFrame + * @static + * @param {protos.RoomDownsyncFrame} message RoomDownsyncFrame + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + RoomDownsyncFrame.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.meleeBullets = []; + if (options.objects || options.defaults) + object.players = {}; + if (options.defaults) { + object.id = 0; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.countdownNanos = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.countdownNanos = options.longs === String ? "0" : 0; + } + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + var keys2; + if (message.players && (keys2 = Object.keys(message.players)).length) { + object.players = {}; + for (var j = 0; j < keys2.length; ++j) + object.players[keys2[j]] = $root.protos.PlayerDownsync.toObject(message.players[keys2[j]], options); + } + if (message.countdownNanos != null && message.hasOwnProperty("countdownNanos")) + if (typeof message.countdownNanos === "number") + object.countdownNanos = options.longs === String ? String(message.countdownNanos) : message.countdownNanos; + else + object.countdownNanos = options.longs === String ? $util.Long.prototype.toString.call(message.countdownNanos) : options.longs === Number ? new $util.LongBits(message.countdownNanos.low >>> 0, message.countdownNanos.high >>> 0).toNumber() : message.countdownNanos; + if (message.meleeBullets && message.meleeBullets.length) { + object.meleeBullets = []; + for (var j = 0; j < message.meleeBullets.length; ++j) + object.meleeBullets[j] = $root.protos.MeleeBullet.toObject(message.meleeBullets[j], options); + } + return object; + }; + + /** + * Converts this RoomDownsyncFrame to JSON. + * @function toJSON + * @memberof protos.RoomDownsyncFrame + * @instance + * @returns {Object.} JSON object + */ + RoomDownsyncFrame.prototype.toJSON = function toJSON() { + 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; + })(); + return protos; })();