Feat: req validate

pull/21/head
zijiren233 2 years ago
parent 2752ab48ac
commit bf1334d1b3

@ -109,11 +109,11 @@ type MovieInfo struct {
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
Live bool `protobuf:"varint,4,opt,name=live,proto3" json:"live,omitempty"` Live bool `protobuf:"varint,4,opt,name=live,proto3" json:"live,omitempty"`
Proxy bool `protobuf:"varint,5,opt,name=proxy,proto3" json:"proxy,omitempty"` Proxy bool `protobuf:"varint,5,opt,name=proxy,proto3" json:"proxy,omitempty"`
RtmpSource bool `protobuf:"varint,6,opt,name=rtmp_source,json=rtmpSource,proto3" json:"rtmp_source,omitempty"` RtmpSource bool `protobuf:"varint,6,opt,name=rtmpSource,proto3" json:"rtmpSource,omitempty"`
Type string `protobuf:"bytes,7,opt,name=type,proto3" json:"type,omitempty"` Type string `protobuf:"bytes,7,opt,name=type,proto3" json:"type,omitempty"`
Headers map[string]string `protobuf:"bytes,8,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` Headers map[string]string `protobuf:"bytes,8,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
PullKey string `protobuf:"bytes,9,opt,name=pull_key,json=pullKey,proto3" json:"pull_key,omitempty"` PullKey string `protobuf:"bytes,9,opt,name=pullKey,proto3" json:"pullKey,omitempty"`
CreatedAt int64 `protobuf:"varint,10,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` CreatedAt int64 `protobuf:"varint,10,opt,name=createdAt,proto3" json:"createdAt,omitempty"`
Creator string `protobuf:"bytes,11,opt,name=creator,proto3" json:"creator,omitempty"` Creator string `protobuf:"bytes,11,opt,name=creator,proto3" json:"creator,omitempty"`
} }
@ -355,7 +355,7 @@ type ElementMessage struct {
Rate float64 `protobuf:"fixed64,4,opt,name=rate,proto3" json:"rate,omitempty"` Rate float64 `protobuf:"fixed64,4,opt,name=rate,proto3" json:"rate,omitempty"`
Seek float64 `protobuf:"fixed64,5,opt,name=seek,proto3" json:"seek,omitempty"` Seek float64 `protobuf:"fixed64,5,opt,name=seek,proto3" json:"seek,omitempty"`
Current *Current `protobuf:"bytes,6,opt,name=current,proto3,oneof" json:"current,omitempty"` Current *Current `protobuf:"bytes,6,opt,name=current,proto3,oneof" json:"current,omitempty"`
PeopleNum int64 `protobuf:"varint,7,opt,name=people_num,json=peopleNum,proto3" json:"people_num,omitempty"` PeopleNum int64 `protobuf:"varint,7,opt,name=peopleNum,proto3" json:"peopleNum,omitempty"`
Time int64 `protobuf:"varint,8,opt,name=time,proto3" json:"time,omitempty"` Time int64 `protobuf:"varint,8,opt,name=time,proto3" json:"time,omitempty"`
} }
@ -451,72 +451,72 @@ var File_proto_message_proto protoreflect.FileDescriptor
var file_proto_message_proto_rawDesc = []byte{ var file_proto_message_proto_rawDesc = []byte{
0x0a, 0x13, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe9, 0x02, 0x0a, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe6, 0x02, 0x0a,
0x09, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x09, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72,
0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04,
0x6c, 0x69, 0x76, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x18, 0x05, 0x20, 0x6c, 0x69, 0x76, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x18, 0x05, 0x20,
0x01, 0x28, 0x08, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x74, 0x01, 0x28, 0x08, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x74,
0x6d, 0x70, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x6d, 0x70, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a,
0x0a, 0x72, 0x74, 0x6d, 0x70, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x72, 0x74, 0x6d, 0x70, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79,
0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x37,
0x37, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x49, 0x6e, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x49, 0x6e, 0x66,
0x66, 0x6f, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x6f, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07,
0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x75, 0x6c, 0x6c, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x75, 0x6c, 0x6c, 0x4b,
0x5f, 0x6b, 0x65, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x75, 0x6c, 0x6c, 0x65, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x75, 0x6c, 0x6c, 0x4b, 0x65,
0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0a,
0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12,
0x41, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x0b, 0x20, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09,
0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x1a, 0x3a, 0x0a, 0x0c, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61,
0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76,
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4a, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4a, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x65, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x65, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x73,
0x52, 0x04, 0x73, 0x65, 0x65, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x65, 0x65, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x72, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x6c, 0x01, 0x52, 0x04, 0x72, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x69,
0x61, 0x79, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x69, 0x6e,
0x79, 0x69, 0x6e, 0x67, 0x22, 0x58, 0x0a, 0x07, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x67, 0x22, 0x58, 0x0a, 0x07, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x05,
0x26, 0x0a, 0x05, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x6d,
0x52, 0x05, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x6f, 0x76, 0x69, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02,
0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x74, 0x61,
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x87, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x86, 0x02, 0x0a, 0x0e,
0x02, 0x0a, 0x0e, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2d,
0x65, 0x12, 0x2d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x70,
0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a,
0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73,
0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x12, 0x0a, 0x04, 0x72, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x72,
0x52, 0x04, 0x72, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x65, 0x6b, 0x18, 0x05, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x65, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28,
0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x73, 0x65, 0x65, 0x6b, 0x12, 0x2d, 0x0a, 0x07, 0x63, 0x75, 0x01, 0x52, 0x04, 0x73, 0x65, 0x65, 0x6b, 0x12, 0x2d, 0x0a, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65,
0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x07, 0x63, 0x2e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x07, 0x63, 0x75, 0x72, 0x72,
0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x65, 0x6f, 0x65, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65,
0x70, 0x6c, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x70, 0x4e, 0x75, 0x6d, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x70, 0x65, 0x6f, 0x70, 0x6c,
0x65, 0x6f, 0x70, 0x6c, 0x65, 0x4e, 0x75, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x65, 0x4e, 0x75, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01,
0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x63, 0x75, 0x72,
0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2a, 0xdb, 0x01, 0x0a, 0x12, 0x45, 0x6c, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x2a, 0xdb, 0x01, 0x0a, 0x12, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55,
0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f,
0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x48, 0x41, 0x54, 0x5f, 0x52, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x48, 0x41, 0x54, 0x5f, 0x4d, 0x45, 0x53, 0x53,
0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x4c, 0x41, 0x41, 0x47, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x4c, 0x41, 0x59, 0x10, 0x03, 0x12,
0x59, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x41, 0x55, 0x53, 0x45, 0x10, 0x04, 0x12, 0x0e, 0x09, 0x0a, 0x05, 0x50, 0x41, 0x55, 0x53, 0x45, 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x48,
0x0a, 0x0a, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x53, 0x45, 0x45, 0x4b, 0x10, 0x05, 0x12, 0x0c, 0x45, 0x43, 0x4b, 0x5f, 0x53, 0x45, 0x45, 0x4b, 0x10, 0x05, 0x12, 0x0c, 0x0a, 0x08, 0x54, 0x4f,
0x0a, 0x08, 0x54, 0x4f, 0x4f, 0x5f, 0x46, 0x41, 0x53, 0x54, 0x10, 0x06, 0x12, 0x0c, 0x0a, 0x08, 0x4f, 0x5f, 0x46, 0x41, 0x53, 0x54, 0x10, 0x06, 0x12, 0x0c, 0x0a, 0x08, 0x54, 0x4f, 0x4f, 0x5f,
0x54, 0x4f, 0x4f, 0x5f, 0x53, 0x4c, 0x4f, 0x57, 0x10, 0x07, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x48, 0x53, 0x4c, 0x4f, 0x57, 0x10, 0x07, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45,
0x41, 0x4e, 0x47, 0x45, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x10, 0x08, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x10, 0x08, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x48, 0x41, 0x4e, 0x47,
0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x45, 0x45, 0x4b, 0x10, 0x09, 0x12, 0x12, 0x0a, 0x0e, 0x45, 0x5f, 0x53, 0x45, 0x45, 0x4b, 0x10, 0x09, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x48, 0x41, 0x4e,
0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x54, 0x10, 0x0a, 0x47, 0x45, 0x5f, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x54, 0x10, 0x0a, 0x12, 0x11, 0x0a, 0x0d,
0x12, 0x11, 0x0a, 0x0d, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x4d, 0x4f, 0x56, 0x49, 0x45, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x4d, 0x4f, 0x56, 0x49, 0x45, 0x53, 0x10, 0x0b, 0x12,
0x53, 0x10, 0x0b, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x50, 0x45, 0x11, 0x0a, 0x0d, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x50, 0x45, 0x4f, 0x50, 0x4c, 0x45,
0x4f, 0x50, 0x4c, 0x45, 0x10, 0x0c, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x10, 0x0c, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x6f, 0x33,
} }
var ( var (

@ -25,11 +25,11 @@ message MovieInfo {
string name = 3; string name = 3;
bool live = 4; bool live = 4;
bool proxy = 5; bool proxy = 5;
bool rtmp_source = 6; bool rtmpSource = 6;
string type = 7; string type = 7;
map<string, string> headers = 8; map<string, string> headers = 8;
string pull_key = 9; string pullKey = 9;
int64 created_at = 10; int64 createdAt = 10;
string creator = 11; string creator = 11;
} }
@ -51,6 +51,6 @@ message ElementMessage {
double rate = 4; double rate = 4;
double seek = 5; double seek = 5;
optional Current current = 6; optional Current current = 6;
int64 people_num = 7; int64 peopleNum = 7;
int64 time = 8; int64 time = 8;
} }

@ -25,7 +25,7 @@ type broadcastMessage struct {
data Message data Message
sender string sender string
sendToSelf bool sendToSelf bool
ignoreID []string ignoreId []string
} }
type BroadcastConf func(*broadcastMessage) type BroadcastConf func(*broadcastMessage)
@ -42,9 +42,9 @@ func WithSendToSelf() BroadcastConf {
} }
} }
func WithIgnoreID(id ...string) BroadcastConf { func WithIgnoreId(id ...string) BroadcastConf {
return func(bm *broadcastMessage) { return func(bm *broadcastMessage) {
bm.ignoreID = append(bm.ignoreID, id...) bm.ignoreId = append(bm.ignoreId, id...)
} }
} }
@ -83,7 +83,7 @@ func (h *hub) Serve() error {
return true return true
} }
} }
if utils.In(message.ignoreID, cli.user.name) { if utils.In(message.ignoreId, cli.user.name) {
return true return true
} }
if err := cli.Send(message.data); err != nil { if err := cli.Send(message.data); err != nil {

@ -15,8 +15,8 @@ import (
) )
var ( var (
ErrRoomIDEmpty = errors.New("roomid is empty") ErrRoomIdEmpty = errors.New("roomid is empty")
ErrRoomIDTooLong = errors.New("roomid is too long") ErrRoomIdTooLong = errors.New("roomid is too long")
ErrAdminPassWordEmpty = errors.New("admin password is empty") ErrAdminPassWordEmpty = errors.New("admin password is empty")
) )
@ -63,15 +63,15 @@ func WithRootUser(u *User) RoomConf {
} }
// Version cant is 0 // Version cant is 0
func NewRoom(RoomID string, Password string, rtmps *rtmps.Server, conf ...RoomConf) (*Room, error) { func NewRoom(RoomId string, Password string, rtmps *rtmps.Server, conf ...RoomConf) (*Room, error) {
if RoomID == "" { if RoomId == "" {
return nil, ErrRoomIDEmpty return nil, ErrRoomIdEmpty
} else if len(RoomID) > 32 { } else if len(RoomId) > 32 {
return nil, ErrRoomIDTooLong return nil, ErrRoomIdTooLong
} }
now := time.Now().UnixMilli() now := time.Now().UnixMilli()
r := &Room{ r := &Room{
id: RoomID, id: RoomId,
rtmps: rtmps, rtmps: rtmps,
lastActive: now, lastActive: now,
createAt: now, createAt: now,
@ -206,7 +206,7 @@ func (r *Room) Hidden() bool {
return atomic.LoadUint32(&r.hidden) == 1 return atomic.LoadUint32(&r.hidden) == 1
} }
func (r *Room) ID() string { func (r *Room) Id() string {
return r.id return r.id
} }

@ -64,7 +64,7 @@ func (rs *Rooms) HasRoom(id string) bool {
func (rs *Rooms) GetRoom(id string) (*Room, error) { func (rs *Rooms) GetRoom(id string) (*Room, error) {
if id == "" { if id == "" {
return nil, ErrRoomIDEmpty return nil, ErrRoomIdEmpty
} }
r, ok := rs.rooms.Load(id) r, ok := rs.rooms.Load(id)
if !ok { if !ok {
@ -78,7 +78,7 @@ func (rs *Rooms) CreateRoom(id string, password string, s *rtmps.Server, conf ..
if err != nil { if err != nil {
return nil, err return nil, err
} }
r, loaded := rs.rooms.LoadOrStore(r.ID(), r) r, loaded := rs.rooms.LoadOrStore(r.Id(), r)
if loaded { if loaded {
return nil, ErrRoomAlreadyExist return nil, ErrRoomAlreadyExist
} }
@ -87,7 +87,7 @@ func (rs *Rooms) CreateRoom(id string, password string, s *rtmps.Server, conf ..
func (rs *Rooms) DelRoom(id string) error { func (rs *Rooms) DelRoom(id string) error {
if id == "" { if id == "" {
return ErrRoomIDEmpty return ErrRoomIdEmpty
} }
r, ok := rs.rooms.LoadAndDelete(id) r, ok := rs.rooms.LoadAndDelete(id)
if !ok { if !ok {

@ -15,7 +15,6 @@ import (
"github.com/go-resty/resty/v2" "github.com/go-resty/resty/v2"
"github.com/golang-jwt/jwt/v5" "github.com/golang-jwt/jwt/v5"
"github.com/google/uuid" "github.com/google/uuid"
json "github.com/json-iterator/go"
"github.com/synctv-org/synctv/internal/conf" "github.com/synctv-org/synctv/internal/conf"
pb "github.com/synctv-org/synctv/proto" pb "github.com/synctv-org/synctv/proto"
"github.com/synctv-org/synctv/proxy" "github.com/synctv-org/synctv/proxy"
@ -88,18 +87,16 @@ func Movies(ctx *gin.Context) {
})) }))
} }
type PushMovieReq = room.BaseMovieInfo
func PushMovie(ctx *gin.Context) { func PushMovie(ctx *gin.Context) {
user := ctx.Value("user").(*room.User) user := ctx.Value("user").(*room.User)
req := new(PushMovieReq) req := model.PushMovieReq{}
if err := json.NewDecoder(ctx.Request.Body).Decode(req); err != nil { if err := model.Decode(ctx, &req); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return return
} }
movie, err := user.NewMovieWithBaseMovie(*req) movie, err := user.NewMovieWithBaseMovie(room.BaseMovieInfo(req))
if err != nil { if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return return
@ -250,8 +247,8 @@ func PushMovie(ctx *gin.Context) {
func NewPublishKey(ctx *gin.Context) { func NewPublishKey(ctx *gin.Context) {
user := ctx.Value("user").(*room.User) user := ctx.Value("user").(*room.User)
req := new(IdReq) req := model.IdReq{}
if err := json.NewDecoder(ctx.Request.Body).Decode(req); err != nil { if err := model.Decode(ctx, &req); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return return
} }
@ -290,26 +287,21 @@ func NewPublishKey(ctx *gin.Context) {
ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{ ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{
"host": host, "host": host,
"app": user.Room().ID(), "app": user.Room().Id(),
"token": token, "token": token,
})) }))
} }
type EditMovieReq struct {
Id uint64 `json:"id"`
room.BaseMovieInfo
}
func EditMovie(ctx *gin.Context) { func EditMovie(ctx *gin.Context) {
user := ctx.Value("user").(*room.User) user := ctx.Value("user").(*room.User)
req := new(EditMovieReq) req := model.EditMovieReq{}
if err := json.NewDecoder(ctx.Request.Body).Decode(req); err != nil { if err := model.Decode(ctx, &req); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return return
} }
if err := user.EditMovie(req.Id, req.BaseMovieInfo); err != nil { if err := user.EditMovie(req.Id, room.BaseMovieInfo(req.PushMovieReq)); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return return
} }
@ -327,15 +319,11 @@ func EditMovie(ctx *gin.Context) {
ctx.Status(http.StatusNoContent) ctx.Status(http.StatusNoContent)
} }
type IdsReq struct {
Ids []uint64 `json:"ids"`
}
func DelMovie(ctx *gin.Context) { func DelMovie(ctx *gin.Context) {
user := ctx.Value("user").(*room.User) user := ctx.Value("user").(*room.User)
req := new(IdsReq) req := model.IdsReq{}
if err := json.NewDecoder(ctx.Request.Body).Decode(req); err != nil { if err := model.Decode(ctx, &req); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return return
} }
@ -379,16 +367,11 @@ func ClearMovies(ctx *gin.Context) {
ctx.Status(http.StatusNoContent) ctx.Status(http.StatusNoContent)
} }
type SwapMovieReq struct {
Id1 uint64 `json:"id1"`
Id2 uint64 `json:"id2"`
}
func SwapMovie(ctx *gin.Context) { func SwapMovie(ctx *gin.Context) {
user := ctx.Value("user").(*room.User) user := ctx.Value("user").(*room.User)
req := new(SwapMovieReq) req := model.SwapMovieReq{}
if err := json.NewDecoder(ctx.Request.Body).Decode(req); err != nil { if err := model.Decode(ctx, &req); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return return
} }
@ -411,15 +394,11 @@ func SwapMovie(ctx *gin.Context) {
ctx.Status(http.StatusNoContent) ctx.Status(http.StatusNoContent)
} }
type IdReq struct {
Id uint64 `json:"id"`
}
func ChangeCurrentMovie(ctx *gin.Context) { func ChangeCurrentMovie(ctx *gin.Context) {
user := ctx.Value("user").(*room.User) user := ctx.Value("user").(*room.User)
req := new(IdReq) req := model.IdReq{}
if err := json.NewDecoder(ctx.Request.Body).Decode(req); err != nil { if err := model.Decode(ctx, &req); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return return
} }

@ -7,7 +7,6 @@ import (
"strconv" "strconv"
"time" "time"
json "github.com/json-iterator/go"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -32,19 +31,11 @@ func (e FormatErrNotSupportPosition) Error() string {
return fmt.Sprintf("not support position %s", string(e)) return fmt.Sprintf("not support position %s", string(e))
} }
type CreateRoomReq struct {
RoomID string `json:"roomId"`
Password string `json:"password"`
Username string `json:"username"`
UserPassword string `json:"userPassword"`
Hidden bool `json:"hidden"`
}
func NewCreateRoomHandler(s *rtmps.Server) gin.HandlerFunc { func NewCreateRoomHandler(s *rtmps.Server) gin.HandlerFunc {
return func(ctx *gin.Context) { return func(ctx *gin.Context) {
rooms := ctx.Value("rooms").(*room.Rooms) rooms := ctx.Value("rooms").(*room.Rooms)
req := new(CreateRoomReq) req := model.CreateRoomReq{}
if err := json.NewDecoder(ctx.Request.Body).Decode(req); err != nil { if err := model.Decode(ctx, &req); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return return
} }
@ -55,7 +46,7 @@ func NewCreateRoomHandler(s *rtmps.Server) gin.HandlerFunc {
return return
} }
r, err := rooms.CreateRoom(req.RoomID, req.Password, s, r, err := rooms.CreateRoom(req.RoomId, req.Password, s,
room.WithHidden(req.Hidden), room.WithHidden(req.Hidden),
room.WithRootUser(user), room.WithRootUser(user),
) )
@ -79,7 +70,7 @@ func NewCreateRoomHandler(s *rtmps.Server) gin.HandlerFunc {
var pre int64 = 0 var pre int64 = 0
for range ticker.C { for range ticker.C {
if r.Closed() { if r.Closed() {
log.Debugf("ws: room %s closed, stop broadcast people num", r.ID()) log.Debugf("ws: room %s closed, stop broadcast people num", r.Id())
return return
} }
current := r.ClientNum() current := r.ClientNum()
@ -90,13 +81,13 @@ func NewCreateRoomHandler(s *rtmps.Server) gin.HandlerFunc {
PeopleNum: current, PeopleNum: current,
}, },
}); err != nil { }); err != nil {
log.Errorf("ws: room %s broadcast people num error: %v", r.ID(), err) log.Errorf("ws: room %s broadcast people num error: %v", r.Id(), err)
continue continue
} }
pre = current pre = current
} else { } else {
if err := r.Broadcast(&room.PingMessage{}); err != nil { if err := r.Broadcast(&room.PingMessage{}); err != nil {
log.Errorf("ws: room %s broadcast ping error: %v", r.ID(), err) log.Errorf("ws: room %s broadcast ping error: %v", r.Id(), err)
continue continue
} }
} }
@ -109,25 +100,17 @@ func NewCreateRoomHandler(s *rtmps.Server) gin.HandlerFunc {
} }
} }
type RoomListResp struct {
RoomID string `json:"roomId"`
PeopleNum int64 `json:"peopleNum"`
NeedPassword bool `json:"needPassword"`
Creator string `json:"creator"`
CreateAt int64 `json:"createAt"`
}
func RoomList(ctx *gin.Context) { func RoomList(ctx *gin.Context) {
rooms := ctx.Value("rooms").(*room.Rooms) rooms := ctx.Value("rooms").(*room.Rooms)
r := rooms.ListNonHidden() r := rooms.ListNonHidden()
resp := vec.New[*RoomListResp](vec.WithCmpLess[*RoomListResp](func(v1, v2 *RoomListResp) bool { resp := vec.New[*model.RoomListResp](vec.WithCmpLess[*model.RoomListResp](func(v1, v2 *model.RoomListResp) bool {
return v1.PeopleNum < v2.PeopleNum return v1.PeopleNum < v2.PeopleNum
}), vec.WithCmpEqual[*RoomListResp](func(v1, v2 *RoomListResp) bool { }), vec.WithCmpEqual[*model.RoomListResp](func(v1, v2 *model.RoomListResp) bool {
return v1.PeopleNum == v2.PeopleNum return v1.PeopleNum == v2.PeopleNum
})) }))
for _, v := range r { for _, v := range r {
resp.Push(&RoomListResp{ resp.Push(&model.RoomListResp{
RoomID: v.ID(), RoomId: v.Id(),
PeopleNum: v.ClientNum(), PeopleNum: v.ClientNum(),
NeedPassword: v.NeedPassword(), NeedPassword: v.NeedPassword(),
Creator: v.RootUser().Name(), Creator: v.RootUser().Name(),
@ -139,27 +122,27 @@ func RoomList(ctx *gin.Context) {
case "peopleNum": case "peopleNum":
resp.SortStable() resp.SortStable()
case "creator": case "creator":
resp.SortStableFunc(func(v1, v2 *RoomListResp) bool { resp.SortStableFunc(func(v1, v2 *model.RoomListResp) bool {
return natural.Less(v1.Creator, v2.Creator) return natural.Less(v1.Creator, v2.Creator)
}, func(t1, t2 *RoomListResp) bool { }, func(t1, t2 *model.RoomListResp) bool {
return t1.Creator == t2.Creator return t1.Creator == t2.Creator
}) })
case "createAt": case "createAt":
resp.SortStableFunc(func(v1, v2 *RoomListResp) bool { resp.SortStableFunc(func(v1, v2 *model.RoomListResp) bool {
return v1.CreateAt < v2.CreateAt return v1.CreateAt < v2.CreateAt
}, func(t1, t2 *RoomListResp) bool { }, func(t1, t2 *model.RoomListResp) bool {
return t1.CreateAt == t2.CreateAt return t1.CreateAt == t2.CreateAt
}) })
case "roomId": case "roomId":
resp.SortStableFunc(func(v1, v2 *RoomListResp) bool { resp.SortStableFunc(func(v1, v2 *model.RoomListResp) bool {
return natural.Less(v1.RoomID, v2.RoomID) return natural.Less(v1.RoomId, v2.RoomId)
}, func(t1, t2 *RoomListResp) bool { }, func(t1, t2 *model.RoomListResp) bool {
return t1.RoomID == t2.RoomID return t1.RoomId == t2.RoomId
}) })
case "needPassword": case "needPassword":
resp.SortStableFunc(func(v1, v2 *RoomListResp) bool { resp.SortStableFunc(func(v1, v2 *model.RoomListResp) bool {
return v1.NeedPassword && !v2.NeedPassword return v1.NeedPassword && !v2.NeedPassword
}, func(t1, t2 *RoomListResp) bool { }, func(t1, t2 *model.RoomListResp) bool {
return t1.NeedPassword == t2.NeedPassword return t1.NeedPassword == t2.NeedPassword
}) })
default: default:
@ -224,17 +207,10 @@ func CheckUser(ctx *gin.Context) {
})) }))
} }
type LoginRoomReq struct {
RoomID string `json:"roomId"`
Password string `json:"password"`
Username string `json:"username"`
UserPassword string `json:"userPassword"`
}
func LoginRoom(ctx *gin.Context) { func LoginRoom(ctx *gin.Context) {
rooms := ctx.Value("rooms").(*room.Rooms) rooms := ctx.Value("rooms").(*room.Rooms)
req := new(LoginRoomReq) req := model.LoginRoomReq{}
if err := json.NewDecoder(ctx.Request.Body).Decode(req); err != nil { if err := model.Decode(ctx, &req); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return return
} }
@ -249,13 +225,13 @@ func LoginRoom(ctx *gin.Context) {
user *room.User user *room.User
) )
if autoNew { if autoNew {
user, err = middlewares.AuthOrNewWithPassword(req.RoomID, req.Password, req.Username, req.UserPassword, rooms) user, err = middlewares.AuthOrNewWithPassword(req.RoomId, req.Password, req.Username, req.UserPassword, rooms)
if err != nil { if err != nil {
ctx.AbortWithStatusJSON(http.StatusUnauthorized, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusUnauthorized, model.NewApiErrorResp(err))
return return
} }
} else { } else {
user, err = middlewares.AuthWithPassword(req.RoomID, req.Password, req.Username, req.UserPassword, rooms) user, err = middlewares.AuthWithPassword(req.RoomId, req.Password, req.Username, req.UserPassword, rooms)
if err != nil { if err != nil {
ctx.AbortWithStatusJSON(http.StatusUnauthorized, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusUnauthorized, model.NewApiErrorResp(err))
return return
@ -282,7 +258,7 @@ func DeleteRoom(ctx *gin.Context) {
return return
} }
err := rooms.DelRoom(user.Room().ID()) err := rooms.DelRoom(user.Room().Id())
if err != nil { if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return return
@ -291,10 +267,6 @@ func DeleteRoom(ctx *gin.Context) {
ctx.Status(http.StatusNoContent) ctx.Status(http.StatusNoContent)
} }
type SetPasswordReq struct {
Password string `json:"password"`
}
func SetPassword(ctx *gin.Context) { func SetPassword(ctx *gin.Context) {
user := ctx.Value("user").(*room.User) user := ctx.Value("user").(*room.User)
@ -303,8 +275,8 @@ func SetPassword(ctx *gin.Context) {
return return
} }
req := new(SetPasswordReq) req := model.SetRoomPasswordReq{}
if err := json.NewDecoder(ctx.Request.Body).Decode(req); err != nil { if err := model.Decode(ctx, &req); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return return
} }
@ -322,10 +294,6 @@ func SetPassword(ctx *gin.Context) {
})) }))
} }
type UsernameReq struct {
Username string `json:"username"`
}
func AddAdmin(ctx *gin.Context) { func AddAdmin(ctx *gin.Context) {
user := ctx.Value("user").(*room.User) user := ctx.Value("user").(*room.User)
@ -334,8 +302,8 @@ func AddAdmin(ctx *gin.Context) {
return return
} }
req := new(UsernameReq) req := model.UsernameReq{}
if err := json.NewDecoder(ctx.Request.Body).Decode(req); err != nil { if err := model.Decode(ctx, &req); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return return
} }
@ -359,8 +327,8 @@ func DelAdmin(ctx *gin.Context) {
return return
} }
req := new(UsernameReq) req := model.UsernameReq{}
if err := json.NewDecoder(ctx.Request.Body).Decode(req); err != nil { if err := model.Decode(ctx, &req); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return return
} }

@ -4,7 +4,6 @@ import (
"net/http" "net/http"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
json "github.com/json-iterator/go"
"github.com/synctv-org/synctv/room" "github.com/synctv-org/synctv/room"
"github.com/synctv-org/synctv/server/middlewares" "github.com/synctv-org/synctv/server/middlewares"
"github.com/synctv-org/synctv/server/model" "github.com/synctv-org/synctv/server/model"
@ -24,8 +23,8 @@ func Me(ctx *gin.Context) {
func SetUserPassword(ctx *gin.Context) { func SetUserPassword(ctx *gin.Context) {
user := ctx.Value("user").(*room.User) user := ctx.Value("user").(*room.User)
req := new(SetPasswordReq) req := model.SetUserPasswordReq{}
if err := json.NewDecoder(ctx.Request.Body).Decode(req); err != nil { if err := model.Decode(ctx, &req); err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return return
} }

@ -48,11 +48,11 @@ func NewWSMessageHandler(u *room.User) func(c *websocket.Conn) error {
} }
return c.WriteMessage(websocket.TextMessage, b) return c.WriteMessage(websocket.TextMessage, b)
} }
log.Infof("ws: room %s user %s connected", u.Room().ID(), u.Name()) log.Infof("ws: room %s user %s connected", u.Room().Id(), u.Name())
defer func() { defer func() {
client.Unregister() client.Unregister()
client.Close() client.Close()
log.Infof("ws: room %s user %s disconnected", u.Room().ID(), u.Name()) log.Infof("ws: room %s user %s disconnected", u.Room().Id(), u.Name())
}() }()
go handleReaderMessage(client) go handleReaderMessage(client)
return handleWriterMessage(client) return handleWriterMessage(client)
@ -63,12 +63,12 @@ func handleWriterMessage(c *room.Client) error {
for v := range c.GetReadChan() { for v := range c.GetReadChan() {
wc, err := c.NextWriter(v.MessageType()) wc, err := c.NextWriter(v.MessageType())
if err != nil { if err != nil {
log.Debugf("ws: room %s user %s get next writer error: %v", c.Room().ID(), c.Username(), err) log.Debugf("ws: room %s user %s get next writer error: %v", c.Room().Id(), c.Username(), err)
return err return err
} }
if err := v.Encode(wc); err != nil { if err := v.Encode(wc); err != nil {
log.Debugf("ws: room %s user %s encode message error: %v", c.Room().ID(), c.Username(), err) log.Debugf("ws: room %s user %s encode message error: %v", c.Room().Id(), c.Username(), err)
continue continue
} }
if err := wc.Close(); err != nil { if err := wc.Close(); err != nil {
@ -84,61 +84,61 @@ func handleReaderMessage(c *room.Client) error {
for { for {
t, rd, err := c.NextReader() t, rd, err := c.NextReader()
if err != nil { if err != nil {
log.Debugf("ws: room %s user %s get next reader error: %v", c.Room().ID(), c.Username(), err) log.Debugf("ws: room %s user %s get next reader error: %v", c.Room().Id(), c.Username(), err)
return err return err
} }
log.Debugf("ws: room %s user %s receive message type: %d", c.Room().ID(), c.Username(), t) log.Debugf("ws: room %s user %s receive message type: %d", c.Room().Id(), c.Username(), t)
switch t { switch t {
case websocket.CloseMessage: case websocket.CloseMessage:
log.Debugf("ws: room %s user %s receive close message", c.Room().ID(), c.Username()) log.Debugf("ws: room %s user %s receive close message", c.Room().Id(), c.Username())
return nil return nil
case websocket.BinaryMessage: case websocket.BinaryMessage:
var data []byte var data []byte
if data, err = io.ReadAll(rd); err != nil { if data, err = io.ReadAll(rd); err != nil {
log.Errorf("ws: room %s user %s read message error: %v", c.Room().ID(), c.Username(), err) log.Errorf("ws: room %s user %s read message error: %v", c.Room().Id(), c.Username(), err)
if err := c.Send(&room.ElementMessage{ if err := c.Send(&room.ElementMessage{
ElementMessage: &pb.ElementMessage{ ElementMessage: &pb.ElementMessage{
Type: pb.ElementMessageType_ERROR, Type: pb.ElementMessageType_ERROR,
Message: err.Error(), Message: err.Error(),
}, },
}); err != nil { }); err != nil {
log.Errorf("ws: room %s user %s send error message error: %v", c.Room().ID(), c.Username(), err) log.Errorf("ws: room %s user %s send error message error: %v", c.Room().Id(), c.Username(), err)
return err return err
} }
continue continue
} }
if err := proto.Unmarshal(data, &msg); err != nil { if err := proto.Unmarshal(data, &msg); err != nil {
log.Errorf("ws: room %s user %s decode message error: %v", c.Room().ID(), c.Username(), err) log.Errorf("ws: room %s user %s decode message error: %v", c.Room().Id(), c.Username(), err)
if err := c.Send(&room.ElementMessage{ if err := c.Send(&room.ElementMessage{
ElementMessage: &pb.ElementMessage{ ElementMessage: &pb.ElementMessage{
Type: pb.ElementMessageType_ERROR, Type: pb.ElementMessageType_ERROR,
Message: err.Error(), Message: err.Error(),
}, },
}); err != nil { }); err != nil {
log.Errorf("ws: room %s user %s send error message error: %v", c.Room().ID(), c.Username(), err) log.Errorf("ws: room %s user %s send error message error: %v", c.Room().Id(), c.Username(), err)
return err return err
} }
continue continue
} }
case websocket.TextMessage: case websocket.TextMessage:
if err := json.NewDecoder(rd).Decode(&msg); err != nil { if err := json.NewDecoder(rd).Decode(&msg); err != nil {
log.Errorf("ws: room %s user %s decode message error: %v", c.Room().ID(), c.Username(), err) log.Errorf("ws: room %s user %s decode message error: %v", c.Room().Id(), c.Username(), err)
if err := c.Send(&room.ElementMessage{ if err := c.Send(&room.ElementMessage{
ElementMessage: &pb.ElementMessage{ ElementMessage: &pb.ElementMessage{
Type: pb.ElementMessageType_ERROR, Type: pb.ElementMessageType_ERROR,
Message: err.Error(), Message: err.Error(),
}, },
}); err != nil { }); err != nil {
log.Errorf("ws: room %s user %s send error message error: %v", c.Room().ID(), c.Username(), err) log.Errorf("ws: room %s user %s send error message error: %v", c.Room().Id(), c.Username(), err)
return err return err
} }
continue continue
} }
default: default:
log.Errorf("ws: room %s user %s receive unknown message type: %d", c.Room().ID(), c.Username(), t) log.Errorf("ws: room %s user %s receive unknown message type: %d", c.Room().Id(), c.Username(), t)
continue continue
} }
log.Debugf("ws: receive room %s user %s message: %+v", c.Room().ID(), c.Username(), msg.String()) log.Debugf("ws: receive room %s user %s message: %+v", c.Room().Id(), c.Username(), msg.String())
switch t { switch t {
case websocket.BinaryMessage: case websocket.BinaryMessage:
err = handleElementMsg(c.Room(), &msg, func(em *pb.ElementMessage) error { err = handleElementMsg(c.Room(), &msg, func(em *pb.ElementMessage) error {
@ -158,7 +158,7 @@ func handleReaderMessage(c *room.Client) error {
}) })
} }
if err != nil { if err != nil {
log.Errorf("ws: room %s user %s handle message error: %v", c.Room().ID(), c.Username(), err) log.Errorf("ws: room %s user %s handle message error: %v", c.Room().Id(), c.Username(), err)
return err return err
} }
} }

@ -19,7 +19,7 @@ var (
) )
type AuthClaims struct { type AuthClaims struct {
RoomID string `json:"id"` RoomId string `json:"id"`
Version uint64 `json:"v"` Version uint64 `json:"v"`
Username string `json:"un"` Username string `json:"un"`
UserVersion uint64 `json:"uv"` UserVersion uint64 `json:"uv"`
@ -45,7 +45,7 @@ func Auth(Authorization string, rooms *room.Rooms) (*room.User, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
r, err := rooms.GetRoom(claims.RoomID) r, err := rooms.GetRoom(claims.RoomId)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -66,8 +66,8 @@ func Auth(Authorization string, rooms *room.Rooms) (*room.User, error) {
return user, nil return user, nil
} }
func AuthWithPassword(roomID, roomPassword, username, password string, rooms *room.Rooms) (*room.User, error) { func AuthWithPassword(roomId, roomPassword, username, password string, rooms *room.Rooms) (*room.User, error) {
room, err := rooms.GetRoom(roomID) room, err := rooms.GetRoom(roomId)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -84,8 +84,8 @@ func AuthWithPassword(roomID, roomPassword, username, password string, rooms *ro
return user, nil return user, nil
} }
func AuthOrNewWithPassword(roomID, roomPassword, username, password string, rooms *room.Rooms) (*room.User, error) { func AuthOrNewWithPassword(roomId, roomPassword, username, password string, rooms *room.Rooms) (*room.User, error) {
room, err := rooms.GetRoom(roomID) room, err := rooms.GetRoom(roomId)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -116,7 +116,7 @@ func AuthRoom(ctx *gin.Context) {
func NewAuthToken(user *room.User) (string, error) { func NewAuthToken(user *room.User) (string, error) {
claims := &AuthClaims{ claims := &AuthClaims{
RoomID: user.Room().ID(), RoomId: user.Room().Id(),
Version: user.Room().Version(), Version: user.Room().Version(),
Username: user.Name(), Username: user.Name(),
UserVersion: user.Version(), UserVersion: user.Version(),

@ -0,0 +1,18 @@
package model
import "github.com/gin-gonic/gin"
type Decoder interface {
Decode(ctx *gin.Context) error
Validate() error
}
func Decode(ctx *gin.Context, decoder Decoder) error {
if err := decoder.Decode(ctx); err != nil {
return err
}
if err := decoder.Validate(); err != nil {
return err
}
return nil
}

@ -0,0 +1,109 @@
package model
import (
"errors"
"github.com/gin-gonic/gin"
json "github.com/json-iterator/go"
"github.com/synctv-org/synctv/room"
)
var (
ErrUrlTooLong = errors.New("url too long")
ErrEmptyName = errors.New("empty name")
ErrNameTooLong = errors.New("name too long")
ErrTypeTooLong = errors.New("type too long")
ErrId = errors.New("id must be greater than 0")
ErrEmptyIds = errors.New("empty ids")
)
type PushMovieReq room.BaseMovieInfo
func (p *PushMovieReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(p)
}
func (p *PushMovieReq) Validate() error {
if len(p.Url) > 1024 {
return ErrUrlTooLong
}
if p.Name == "" {
return ErrEmptyName
} else if len(p.Name) > 1024 {
return ErrNameTooLong
}
if len(p.Type) > 32 {
return ErrTypeTooLong
}
return nil
}
type IdReq struct {
Id uint64 `json:"id"`
}
func (i *IdReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(i)
}
func (i *IdReq) Validate() error {
if i.Id <= 0 {
return ErrId
}
return nil
}
type EditMovieReq struct {
IdReq
PushMovieReq
}
func (e *EditMovieReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(e)
}
func (e *EditMovieReq) Validate() error {
if err := e.IdReq.Validate(); err != nil {
return err
}
if err := e.PushMovieReq.Validate(); err != nil {
return err
}
return nil
}
type IdsReq struct {
Ids []uint64 `json:"ids"`
}
func (i *IdsReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(i)
}
func (i *IdsReq) Validate() error {
if len(i.Ids) == 0 {
return ErrEmptyIds
}
return nil
}
type SwapMovieReq struct {
Id1 uint64 `json:"id1"`
Id2 uint64 `json:"id2"`
}
func (s *SwapMovieReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(s)
}
func (s *SwapMovieReq) Validate() error {
if s.Id1 <= 0 || s.Id2 <= 0 {
return ErrId
}
return nil
}

@ -0,0 +1,138 @@
package model
import (
"errors"
"regexp"
json "github.com/json-iterator/go"
"github.com/gin-gonic/gin"
)
var (
ErrEmptyRoomId = errors.New("empty room id")
ErrRoomIdTooLong = errors.New("room id too long")
ErrRoomIdHasInvalidChar = errors.New("room id has invalid char")
ErrEmptyPassword = errors.New("empty password")
ErrPasswordTooLong = errors.New("password too long")
ErrEmptyUsername = errors.New("empty username")
ErrUsernameTooLong = errors.New("username too long")
ErrUsernameHasInvalidChar = errors.New("username has invalid char")
)
var (
alphaNumReg = regexp.MustCompile(`^[a-zA-Z0-9_-]+$`)
)
type CreateRoomReq struct {
RoomId string `json:"roomId"`
Password string `json:"password"`
Username string `json:"username"`
UserPassword string `json:"userPassword"`
Hidden bool `json:"hidden"`
}
func (c *CreateRoomReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(c)
}
func (c *CreateRoomReq) Validate() error {
if c.RoomId == "" {
return ErrEmptyRoomId
} else if len(c.RoomId) > 32 {
return ErrRoomIdTooLong
} else if !alphaNumReg.MatchString(c.RoomId) {
return ErrRoomIdHasInvalidChar
}
if len(c.Password) > 32 {
return ErrPasswordTooLong
}
if c.Username == "" {
return ErrEmptyUsername
} else if len(c.Username) > 32 {
return ErrUsernameTooLong
} else if !alphaNumReg.MatchString(c.Username) {
return ErrUsernameHasInvalidChar
}
if c.UserPassword == "" {
return ErrEmptyPassword
} else if len(c.UserPassword) > 32 {
return ErrPasswordTooLong
}
return nil
}
type RoomListResp struct {
RoomId string `json:"roomId"`
PeopleNum int64 `json:"peopleNum"`
NeedPassword bool `json:"needPassword"`
Creator string `json:"creator"`
CreateAt int64 `json:"createAt"`
}
type LoginRoomReq struct {
RoomId string `json:"roomId"`
Password string `json:"password"`
Username string `json:"username"`
UserPassword string `json:"userPassword"`
}
func (l *LoginRoomReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(l)
}
func (l *LoginRoomReq) Validate() error {
if l.RoomId == "" {
return ErrEmptyRoomId
}
if l.Username == "" {
return ErrEmptyUsername
}
if l.UserPassword == "" {
return ErrEmptyPassword
}
return nil
}
type SetRoomPasswordReq struct {
Password string `json:"password"`
}
func (s *SetRoomPasswordReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(s)
}
func (s *SetRoomPasswordReq) Validate() error {
if len(s.Password) > 32 {
return ErrPasswordTooLong
}
return nil
}
type UsernameReq struct {
Username string `json:"username"`
}
func (u *UsernameReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(u)
}
func (u *UsernameReq) Validate() error {
if u.Username == "" {
return ErrEmptyUsername
} else if len(u.Username) > 32 {
return ErrUsernameTooLong
} else if !alphaNumReg.MatchString(u.Username) {
return ErrUsernameHasInvalidChar
}
return nil
}

@ -0,0 +1,23 @@
package model
import (
"github.com/gin-gonic/gin"
json "github.com/json-iterator/go"
)
type SetUserPasswordReq struct {
Password string `json:"password"`
}
func (s *SetUserPasswordReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(s)
}
func (s *SetUserPasswordReq) Validate() error {
if s.Password == "" {
return ErrEmptyPassword
} else if len(s.Password) > 32 {
return ErrPasswordTooLong
}
return nil
}
Loading…
Cancel
Save