refactor: pb proto and sync member status

api-v2
zijiren233 1 year ago
parent b8fa101412
commit ed3ed467fc

@ -47,15 +47,15 @@ func (c *Client) SendChatMessage(message string) error {
if !c.u.HasRoomPermission(c.r, model.PermissionSendChatMessage) {
return model.ErrNoPermission
}
return c.Broadcast(&pb.ElementMessage{
Type: pb.ElementMessageType_CHAT_MESSAGE,
Time: time.Now().UnixMilli(),
ChatResp: &pb.ChatResp{
Message: message,
Sender: &pb.Sender{
Userid: c.u.ID,
Username: c.u.Username,
},
return c.Broadcast(&pb.Message{
Type: pb.MessageType_CHAT,
Timestamp: time.Now().UnixMilli(),
Sender: &pb.Sender{
UserId: c.u.ID,
Username: c.u.Username,
},
Payload: &pb.Message_ChatContent{
ChatContent: message,
},
})
}
@ -95,10 +95,23 @@ func (c *Client) NextReader() (int, io.Reader, error) {
return c.conn.NextReader()
}
func (c *Client) SetSeekRate(seek float64, rate float64, timeDiff float64) (*Status, error) {
return c.u.SetRoomCurrentSeekRate(c.r, seek, rate, timeDiff)
}
func (c *Client) SetStatus(playing bool, seek float64, rate float64, timeDiff float64) (*Status, error) {
return c.u.SetRoomCurrentStatus(c.r, playing, seek, rate, timeDiff)
func (c *Client) SetStatus(playing bool, seek float64, rate float64, timeDiff float64) error {
status, err := c.u.SetRoomCurrentStatus(c.r, playing, seek, rate, timeDiff)
if err != nil {
return err
}
return c.Broadcast(&pb.Message{
Type: pb.MessageType_STATUS,
Sender: &pb.Sender{
Username: c.User().Username,
UserId: c.User().ID,
},
Payload: &pb.Message_PlaybackStatus{
PlaybackStatus: &pb.Status{
IsPlaying: status.IsPlaying,
CurrentTime: status.CurrentTime,
PlaybackRate: status.PlaybackRate,
},
},
}, WithIgnoreClient(c))
}

@ -29,17 +29,17 @@ func newCurrent() *current {
}
type Status struct {
Seek float64 `json:"seek"`
Rate float64 `json:"rate"`
Playing bool `json:"playing"`
lastUpdate time.Time `json:"-"`
CurrentTime float64 `json:"currentTime"`
PlaybackRate float64 `json:"playbackRate"`
IsPlaying bool `json:"isPlaying"`
lastUpdate time.Time `json:"-"`
}
func newStatus() Status {
return Status{
Seek: 0,
Rate: 1.0,
lastUpdate: time.Now(),
CurrentTime: 0,
PlaybackRate: 1.0,
lastUpdate: time.Now(),
}
}
@ -56,7 +56,7 @@ func (c *current) SetMovie(movie CurrentMovie, play bool) {
c.current.Movie = movie
c.current.SetSeek(0, 0)
c.current.Status.Playing = play
c.current.Status.IsPlaying = play
}
func (c *current) Status() Status {
@ -87,17 +87,17 @@ func (c *Current) UpdateStatus() Status {
c.Status.lastUpdate = time.Now()
return c.Status
}
if c.Status.Playing {
c.Status.Seek += time.Since(c.Status.lastUpdate).Seconds() * c.Status.Rate
if c.Status.IsPlaying {
c.Status.CurrentTime += time.Since(c.Status.lastUpdate).Seconds() * c.Status.PlaybackRate
}
c.Status.lastUpdate = time.Now()
return c.Status
}
func (c *Current) setLiveStatus() Status {
c.Status.Playing = true
c.Status.Rate = 1.0
c.Status.Seek = 0
c.Status.IsPlaying = true
c.Status.PlaybackRate = 1.0
c.Status.CurrentTime = 0
c.Status.lastUpdate = time.Now()
return c.Status
}
@ -106,12 +106,12 @@ func (c *Current) SetStatus(playing bool, seek, rate, timeDiff float64) Status {
if c.Movie.IsLive {
return c.setLiveStatus()
}
c.Status.Playing = playing
c.Status.Rate = rate
c.Status.IsPlaying = playing
c.Status.PlaybackRate = rate
if playing {
c.Status.Seek = seek + (timeDiff * rate)
c.Status.CurrentTime = seek + (timeDiff * rate)
} else {
c.Status.Seek = seek
c.Status.CurrentTime = seek
}
c.Status.lastUpdate = time.Now()
return c.Status
@ -121,12 +121,12 @@ func (c *Current) SetSeekRate(seek, rate, timeDiff float64) Status {
if c.Movie.IsLive {
return c.setLiveStatus()
}
if c.Status.Playing {
c.Status.Seek = seek + (timeDiff * rate)
if c.Status.IsPlaying {
c.Status.CurrentTime = seek + (timeDiff * rate)
} else {
c.Status.Seek = seek
c.Status.CurrentTime = seek
}
c.Status.Rate = rate
c.Status.PlaybackRate = rate
c.Status.lastUpdate = time.Now()
return c.Status
}
@ -135,10 +135,10 @@ func (c *Current) SetSeek(seek, timeDiff float64) Status {
if c.Movie.IsLive {
return c.setLiveStatus()
}
if c.Status.Playing {
c.Status.Seek = seek + (timeDiff * c.Status.Rate)
if c.Status.IsPlaying {
c.Status.CurrentTime = seek + (timeDiff * c.Status.PlaybackRate)
} else {
c.Status.Seek = seek
c.Status.CurrentTime = seek
}
c.Status.lastUpdate = time.Now()
return c.Status

@ -105,9 +105,11 @@ func (h *Hub) ping() {
case <-ticker.C:
current = h.PeopleNum()
if current != pre {
if err := h.Broadcast(&pb.ElementMessage{
Type: pb.ElementMessageType_PEOPLE_CHANGED,
PeopleChanged: current,
if err := h.Broadcast(&pb.Message{
Type: pb.MessageType_VIEWER_COUNT,
Payload: &pb.Message_ViewerCount{
ViewerCount: current,
},
}); err != nil {
continue
}

@ -53,10 +53,14 @@ func (r *Room) Broadcast(data Message, conf ...BroadcastConf) error {
}
func (r *Room) SendToUser(user *User, data Message) error {
return r.SendToUserWithId(user.ID, data)
}
func (r *Room) SendToUserWithId(userID string, data Message) error {
if r.hub == nil {
return nil
}
return r.hub.SendToUser(user.ID, data)
return r.hub.SendToUser(userID, data)
}
func (r *Room) GetChannel(channelName string) (*rtmps.Channel, error) {
@ -607,7 +611,10 @@ func (r *Room) DeleteMember(userID string) error {
if r.IsCreator(userID) {
return errors.New("you are creator, cannot delete")
}
defer r.members.Delete(userID)
defer func() {
r.members.Delete(userID)
_ = r.KickUser(userID)
}()
return db.DeleteRoomMember(r.ID, userID)
}

@ -138,11 +138,11 @@ func (u *User) AddRoomMovie(room *Room, movie *model.MovieBase) (*model.Movie, e
if err != nil {
return nil, err
}
return m, room.Broadcast(&pb.ElementMessage{
Type: pb.ElementMessageType_MOVIES_CHANGED,
MoviesChanged: &pb.Sender{
return m, room.Broadcast(&pb.Message{
Type: pb.MessageType_MOVIES,
Sender: &pb.Sender{
Username: u.Username,
Userid: u.ID,
UserId: u.ID,
},
})
}
@ -171,11 +171,11 @@ func (u *User) AddRoomMovies(room *Room, movies []*model.MovieBase) ([]*model.Mo
if err != nil {
return nil, err
}
return m, room.Broadcast(&pb.ElementMessage{
Type: pb.ElementMessageType_MOVIES_CHANGED,
MoviesChanged: &pb.Sender{
return m, room.Broadcast(&pb.Message{
Type: pb.MessageType_MOVIES,
Sender: &pb.Sender{
Username: u.Username,
Userid: u.ID,
UserId: u.ID,
},
})
}
@ -315,11 +315,11 @@ func (u *User) UpdateRoomMovie(room *Room, movieID string, movie *model.MovieBas
if err != nil {
return err
}
return room.Broadcast(&pb.ElementMessage{
Type: pb.ElementMessageType_MOVIES_CHANGED,
MoviesChanged: &pb.Sender{
return room.Broadcast(&pb.Message{
Type: pb.MessageType_MOVIES,
Sender: &pb.Sender{
Username: u.Username,
Userid: u.ID,
UserId: u.ID,
},
})
}
@ -362,11 +362,11 @@ func (u *User) DeleteRoomMoviesByID(room *Room, movieIDs []string) error {
if err := room.DeleteMoviesByID(movieIDs); err != nil {
return err
}
return room.Broadcast(&pb.ElementMessage{
Type: pb.ElementMessageType_MOVIES_CHANGED,
MoviesChanged: &pb.Sender{
return room.Broadcast(&pb.Message{
Type: pb.MessageType_MOVIES,
Sender: &pb.Sender{
Username: u.Username,
Userid: u.ID,
UserId: u.ID,
},
})
}
@ -379,11 +379,11 @@ func (u *User) ClearRoomMovies(room *Room) error {
if err != nil {
return err
}
return room.Broadcast(&pb.ElementMessage{
Type: pb.ElementMessageType_MOVIES_CHANGED,
MoviesChanged: &pb.Sender{
return room.Broadcast(&pb.Message{
Type: pb.MessageType_MOVIES,
Sender: &pb.Sender{
Username: u.Username,
Userid: u.ID,
UserId: u.ID,
},
})
}
@ -396,11 +396,11 @@ func (u *User) ClearRoomMoviesByParentID(room *Room, parentID string) error {
if err != nil {
return err
}
return room.Broadcast(&pb.ElementMessage{
Type: pb.ElementMessageType_MOVIES_CHANGED,
MoviesChanged: &pb.Sender{
return room.Broadcast(&pb.Message{
Type: pb.MessageType_MOVIES,
Sender: &pb.Sender{
Username: u.Username,
Userid: u.ID,
UserId: u.ID,
},
})
}
@ -413,11 +413,11 @@ func (u *User) SwapRoomMoviePositions(room *Room, id1, id2 string) error {
if err != nil {
return err
}
return room.Broadcast(&pb.ElementMessage{
Type: pb.ElementMessageType_MOVIES_CHANGED,
MoviesChanged: &pb.Sender{
return room.Broadcast(&pb.Message{
Type: pb.MessageType_MOVIES,
Sender: &pb.Sender{
Username: u.Username,
Userid: u.ID,
UserId: u.ID,
},
})
}
@ -430,11 +430,11 @@ func (u *User) SetRoomCurrentMovie(room *Room, movieID string, subPath string, p
if err != nil {
return err
}
return room.Broadcast(&pb.ElementMessage{
Type: pb.ElementMessageType_CURRENT_CHANGED,
CurrentChanged: &pb.Sender{
return room.Broadcast(&pb.Message{
Type: pb.MessageType_CURRENT,
Sender: &pb.Sender{
Username: u.Username,
Userid: u.ID,
UserId: u.ID,
},
})
}
@ -505,13 +505,6 @@ func (u *User) GetRoomMoviesWithPage(room *Room, page, pageSize int, parentID st
return room.GetMoviesWithPage(page, pageSize, parentID)
}
func (u *User) SetRoomCurrentSeekRate(room *Room, seek, rate, timeDiff float64) (*Status, error) {
if !u.HasRoomPermission(room, model.PermissionSetCurrentStatus) {
return nil, model.ErrNoPermission
}
return room.SetCurrentSeekRate(seek, rate, timeDiff), nil
}
func (u *User) SetRoomCurrentStatus(room *Room, playing bool, seek, rate, timeDiff float64) (*Status, error) {
if !u.HasRoomPermission(room, model.PermissionSetCurrentStatus) {
return nil, model.ErrNoPermission
@ -556,7 +549,17 @@ func (u *User) SetMemberPermissions(room *Room, userID string, permissions model
if room.IsAdmin(userID) && !u.IsRoomCreator(room) {
return errors.New("cannot set admin permissions")
}
return room.SetMemberPermissions(userID, permissions)
err := room.SetMemberPermissions(userID, permissions)
if err != nil {
return err
}
return room.SendToUserWithId(userID, &pb.Message{
Type: pb.MessageType_MY_STATUS,
Sender: &pb.Sender{
Username: u.Username,
UserId: u.ID,
},
})
}
func (u *User) AddMemberPermissions(room *Room, userID string, permissions model.RoomMemberPermission) error {
@ -566,7 +569,17 @@ func (u *User) AddMemberPermissions(room *Room, userID string, permissions model
if room.IsAdmin(userID) && !u.IsRoomCreator(room) {
return errors.New("cannot add admin permissions")
}
return room.AddMemberPermissions(userID, permissions)
err := room.AddMemberPermissions(userID, permissions)
if err != nil {
return err
}
return room.SendToUserWithId(userID, &pb.Message{
Type: pb.MessageType_MY_STATUS,
Sender: &pb.Sender{
Username: u.Username,
UserId: u.ID,
},
})
}
func (u *User) RemoveMemberPermissions(room *Room, userID string, permissions model.RoomMemberPermission) error {
@ -576,7 +589,17 @@ func (u *User) RemoveMemberPermissions(room *Room, userID string, permissions mo
if room.IsAdmin(userID) && !u.IsRoomCreator(room) {
return errors.New("cannot remove admin permissions")
}
return room.RemoveMemberPermissions(userID, permissions)
err := room.RemoveMemberPermissions(userID, permissions)
if err != nil {
return err
}
return room.SendToUserWithId(userID, &pb.Message{
Type: pb.MessageType_MY_STATUS,
Sender: &pb.Sender{
Username: u.Username,
UserId: u.ID,
},
})
}
func (u *User) ResetMemberPermissions(room *Room, userID string) error {
@ -586,7 +609,17 @@ func (u *User) ResetMemberPermissions(room *Room, userID string) error {
if room.IsAdmin(userID) && !u.IsRoomCreator(room) {
return errors.New("cannot reset admin permissions")
}
return room.ResetMemberPermissions(userID)
err := room.ResetMemberPermissions(userID)
if err != nil {
return err
}
return room.SendToUserWithId(userID, &pb.Message{
Type: pb.MessageType_MY_STATUS,
Sender: &pb.Sender{
Username: u.Username,
UserId: u.ID,
},
})
}
func (u *User) ApproveRoomPendingMember(room *Room, userID string) error {
@ -600,40 +633,100 @@ func (u *User) SetRoomAdmin(room *Room, userID string, permissions model.RoomAdm
if !u.IsRoomCreator(room) {
return model.ErrNoPermission
}
return room.SetAdmin(userID, permissions)
err := room.SetAdmin(userID, permissions)
if err != nil {
return err
}
return room.SendToUserWithId(userID, &pb.Message{
Type: pb.MessageType_MY_STATUS,
Sender: &pb.Sender{
Username: u.Username,
UserId: u.ID,
},
})
}
func (u *User) SetRoomMember(room *Room, userID string, permissions model.RoomMemberPermission) error {
if !u.IsRoomCreator(room) {
return model.ErrNoPermission
}
return room.SetMember(userID, permissions)
err := room.SetMember(userID, permissions)
if err != nil {
return err
}
return room.SendToUserWithId(userID, &pb.Message{
Type: pb.MessageType_MY_STATUS,
Sender: &pb.Sender{
Username: u.Username,
UserId: u.ID,
},
})
}
func (u *User) SetRoomAdminPermissions(room *Room, userID string, permissions model.RoomAdminPermission) error {
if !u.IsRoomCreator(room) {
return model.ErrNoPermission
}
return room.SetAdminPermissions(userID, permissions)
err := room.SetAdminPermissions(userID, permissions)
if err != nil {
return err
}
return room.SendToUserWithId(userID, &pb.Message{
Type: pb.MessageType_MY_STATUS,
Sender: &pb.Sender{
Username: u.Username,
UserId: u.ID,
},
})
}
func (u *User) AddRoomAdminPermissions(room *Room, userID string, permissions model.RoomAdminPermission) error {
if !u.IsRoomCreator(room) {
return model.ErrNoPermission
}
return room.AddAdminPermissions(userID, permissions)
err := room.AddAdminPermissions(userID, permissions)
if err != nil {
return err
}
return room.SendToUserWithId(userID, &pb.Message{
Type: pb.MessageType_MY_STATUS,
Sender: &pb.Sender{
Username: u.Username,
UserId: u.ID,
},
})
}
func (u *User) RemoveRoomAdminPermissions(room *Room, userID string, permissions model.RoomAdminPermission) error {
if !u.IsRoomCreator(room) {
return model.ErrNoPermission
}
return room.RemoveAdminPermissions(userID, permissions)
err := room.RemoveAdminPermissions(userID, permissions)
if err != nil {
return err
}
return room.SendToUserWithId(userID, &pb.Message{
Type: pb.MessageType_MY_STATUS,
Sender: &pb.Sender{
Username: u.Username,
UserId: u.ID,
},
})
}
func (u *User) ResetRoomAdminPermissions(room *Room, userID string) error {
if !u.IsRoomCreator(room) {
return model.ErrNoPermission
}
return room.ResetAdminPermissions(userID)
err := room.ResetAdminPermissions(userID)
if err != nil {
return err
}
return room.SendToUserWithId(userID, &pb.Message{
Type: pb.MessageType_MY_STATUS,
Sender: &pb.Sender{
Username: u.Username,
UserId: u.ID,
},
})
}

@ -7,12 +7,12 @@ import (
"google.golang.org/protobuf/proto"
)
func (em *ElementMessage) MessageType() int {
func (em *Message) MessageType() int {
return websocket.BinaryMessage
}
func (em *ElementMessage) Encode(w io.Writer) error {
b, err := proto.Marshal((*ElementMessage)(em))
func (em *Message) Encode(w io.Writer) error {
b, err := proto.Marshal((*Message)(em))
if err != nil {
return err
}

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.34.1
// protoc v5.26.1
// protoc-gen-go v1.35.1
// protoc v5.28.2
// source: proto/message/message.proto
package pb
@ -20,165 +20,93 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type ElementMessageType int32
type MessageType int32
const (
ElementMessageType_UNKNOWN ElementMessageType = 0
ElementMessageType_ERROR ElementMessageType = 1
ElementMessageType_CHAT_MESSAGE ElementMessageType = 2
ElementMessageType_PLAY ElementMessageType = 3
ElementMessageType_PAUSE ElementMessageType = 4
ElementMessageType_CHECK_STATUS ElementMessageType = 5
ElementMessageType_TOO_FAST ElementMessageType = 6
ElementMessageType_TOO_SLOW ElementMessageType = 7
ElementMessageType_CHANGE_RATE ElementMessageType = 8
ElementMessageType_CHANGE_SEEK ElementMessageType = 9
ElementMessageType_CURRENT_CHANGED ElementMessageType = 10
ElementMessageType_MOVIES_CHANGED ElementMessageType = 11
ElementMessageType_PEOPLE_CHANGED ElementMessageType = 12
ElementMessageType_SYNC_MOVIE_STATUS ElementMessageType = 13
ElementMessageType_CURRENT_EXPIRED ElementMessageType = 14
ElementMessageType_CHECK_EXPIRED ElementMessageType = 15
MessageType_UNKNOWN MessageType = 0
MessageType_ERROR MessageType = 1
MessageType_CHAT MessageType = 2
MessageType_STATUS MessageType = 3
MessageType_CHECK_STATUS MessageType = 4
MessageType_EXPIRED MessageType = 5
MessageType_CURRENT MessageType = 6
MessageType_MOVIES MessageType = 7
MessageType_VIEWER_COUNT MessageType = 8
MessageType_SYNC MessageType = 9
MessageType_MY_STATUS MessageType = 10
)
// Enum value maps for ElementMessageType.
// Enum value maps for MessageType.
var (
ElementMessageType_name = map[int32]string{
MessageType_name = map[int32]string{
0: "UNKNOWN",
1: "ERROR",
2: "CHAT_MESSAGE",
3: "PLAY",
4: "PAUSE",
5: "CHECK_STATUS",
6: "TOO_FAST",
7: "TOO_SLOW",
8: "CHANGE_RATE",
9: "CHANGE_SEEK",
10: "CURRENT_CHANGED",
11: "MOVIES_CHANGED",
12: "PEOPLE_CHANGED",
13: "SYNC_MOVIE_STATUS",
14: "CURRENT_EXPIRED",
15: "CHECK_EXPIRED",
}
ElementMessageType_value = map[string]int32{
"UNKNOWN": 0,
"ERROR": 1,
"CHAT_MESSAGE": 2,
"PLAY": 3,
"PAUSE": 4,
"CHECK_STATUS": 5,
"TOO_FAST": 6,
"TOO_SLOW": 7,
"CHANGE_RATE": 8,
"CHANGE_SEEK": 9,
"CURRENT_CHANGED": 10,
"MOVIES_CHANGED": 11,
"PEOPLE_CHANGED": 12,
"SYNC_MOVIE_STATUS": 13,
"CURRENT_EXPIRED": 14,
"CHECK_EXPIRED": 15,
2: "CHAT",
3: "STATUS",
4: "CHECK_STATUS",
5: "EXPIRED",
6: "CURRENT",
7: "MOVIES",
8: "VIEWER_COUNT",
9: "SYNC",
10: "MY_STATUS",
}
MessageType_value = map[string]int32{
"UNKNOWN": 0,
"ERROR": 1,
"CHAT": 2,
"STATUS": 3,
"CHECK_STATUS": 4,
"EXPIRED": 5,
"CURRENT": 6,
"MOVIES": 7,
"VIEWER_COUNT": 8,
"SYNC": 9,
"MY_STATUS": 10,
}
)
func (x ElementMessageType) Enum() *ElementMessageType {
p := new(ElementMessageType)
func (x MessageType) Enum() *MessageType {
p := new(MessageType)
*p = x
return p
}
func (x ElementMessageType) String() string {
func (x MessageType) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (ElementMessageType) Descriptor() protoreflect.EnumDescriptor {
func (MessageType) Descriptor() protoreflect.EnumDescriptor {
return file_proto_message_message_proto_enumTypes[0].Descriptor()
}
func (ElementMessageType) Type() protoreflect.EnumType {
func (MessageType) Type() protoreflect.EnumType {
return &file_proto_message_message_proto_enumTypes[0]
}
func (x ElementMessageType) Number() protoreflect.EnumNumber {
func (x MessageType) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use ElementMessageType.Descriptor instead.
func (ElementMessageType) EnumDescriptor() ([]byte, []int) {
// Deprecated: Use MessageType.Descriptor instead.
func (MessageType) EnumDescriptor() ([]byte, []int) {
return file_proto_message_message_proto_rawDescGZIP(), []int{0}
}
type ChatResp struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Sender *Sender `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"`
Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
}
func (x *ChatResp) Reset() {
*x = ChatResp{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_message_message_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ChatResp) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ChatResp) ProtoMessage() {}
func (x *ChatResp) ProtoReflect() protoreflect.Message {
mi := &file_proto_message_message_proto_msgTypes[0]
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 ChatResp.ProtoReflect.Descriptor instead.
func (*ChatResp) Descriptor() ([]byte, []int) {
return file_proto_message_message_proto_rawDescGZIP(), []int{0}
}
func (x *ChatResp) GetSender() *Sender {
if x != nil {
return x.Sender
}
return nil
}
func (x *ChatResp) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
type Sender struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
Userid string `protobuf:"bytes,2,opt,name=userid,proto3" json:"userid,omitempty"`
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"`
}
func (x *Sender) Reset() {
*x = Sender{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_message_message_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_proto_message_message_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Sender) String() string {
@ -188,8 +116,8 @@ func (x *Sender) String() string {
func (*Sender) ProtoMessage() {}
func (x *Sender) ProtoReflect() protoreflect.Message {
mi := &file_proto_message_message_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
mi := &file_proto_message_message_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -201,51 +129,49 @@ func (x *Sender) ProtoReflect() protoreflect.Message {
// Deprecated: Use Sender.ProtoReflect.Descriptor instead.
func (*Sender) Descriptor() ([]byte, []int) {
return file_proto_message_message_proto_rawDescGZIP(), []int{1}
return file_proto_message_message_proto_rawDescGZIP(), []int{0}
}
func (x *Sender) GetUsername() string {
func (x *Sender) GetUserId() string {
if x != nil {
return x.Username
return x.UserId
}
return ""
}
func (x *Sender) GetUserid() string {
func (x *Sender) GetUsername() string {
if x != nil {
return x.Userid
return x.Username
}
return ""
}
type MovieStatus struct {
type Status struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Playing bool `protobuf:"varint,1,opt,name=playing,proto3" json:"playing,omitempty"`
Seek float64 `protobuf:"fixed64,2,opt,name=seek,proto3" json:"seek,omitempty"`
Rate float64 `protobuf:"fixed64,3,opt,name=rate,proto3" json:"rate,omitempty"`
IsPlaying bool `protobuf:"varint,1,opt,name=is_playing,json=isPlaying,proto3" json:"is_playing,omitempty"`
CurrentTime float64 `protobuf:"fixed64,2,opt,name=current_time,json=currentTime,proto3" json:"current_time,omitempty"`
PlaybackRate float64 `protobuf:"fixed64,3,opt,name=playback_rate,json=playbackRate,proto3" json:"playback_rate,omitempty"`
}
func (x *MovieStatus) Reset() {
*x = MovieStatus{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_message_message_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Status) Reset() {
*x = Status{}
mi := &file_proto_message_message_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *MovieStatus) String() string {
func (x *Status) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*MovieStatus) ProtoMessage() {}
func (*Status) ProtoMessage() {}
func (x *MovieStatus) ProtoReflect() protoreflect.Message {
mi := &file_proto_message_message_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
func (x *Status) ProtoReflect() protoreflect.Message {
mi := &file_proto_message_message_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -255,59 +181,66 @@ func (x *MovieStatus) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use MovieStatus.ProtoReflect.Descriptor instead.
func (*MovieStatus) Descriptor() ([]byte, []int) {
return file_proto_message_message_proto_rawDescGZIP(), []int{2}
// Deprecated: Use Status.ProtoReflect.Descriptor instead.
func (*Status) Descriptor() ([]byte, []int) {
return file_proto_message_message_proto_rawDescGZIP(), []int{1}
}
func (x *MovieStatus) GetPlaying() bool {
func (x *Status) GetIsPlaying() bool {
if x != nil {
return x.Playing
return x.IsPlaying
}
return false
}
func (x *MovieStatus) GetSeek() float64 {
func (x *Status) GetCurrentTime() float64 {
if x != nil {
return x.Seek
return x.CurrentTime
}
return 0
}
func (x *MovieStatus) GetRate() float64 {
func (x *Status) GetPlaybackRate() float64 {
if x != nil {
return x.Rate
return x.PlaybackRate
}
return 0
}
type MovieStatusChanged struct {
type Message struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Sender *Sender `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"`
Status *MovieStatus `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"`
}
func (x *MovieStatusChanged) Reset() {
*x = MovieStatusChanged{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_message_message_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
Type MessageType `protobuf:"varint,1,opt,name=type,proto3,enum=proto.MessageType" json:"type,omitempty"`
Timestamp int64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
Sender *Sender `protobuf:"bytes,3,opt,name=sender,proto3,oneof" json:"sender,omitempty"`
// Types that are assignable to Payload:
//
// *Message_ErrorMessage
// *Message_ChatContent
// *Message_PlaybackStatus
// *Message_ExpirationId
// *Message_ViewerCount
Payload isMessage_Payload `protobuf_oneof:"payload"`
}
func (x *Message) Reset() {
*x = Message{}
mi := &file_proto_message_message_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *MovieStatusChanged) String() string {
func (x *Message) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*MovieStatusChanged) ProtoMessage() {}
func (*Message) ProtoMessage() {}
func (x *MovieStatusChanged) ProtoReflect() protoreflect.Message {
mi := &file_proto_message_message_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
func (x *Message) ProtoReflect() protoreflect.Message {
mi := &file_proto_message_message_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -317,251 +250,158 @@ func (x *MovieStatusChanged) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use MovieStatusChanged.ProtoReflect.Descriptor instead.
func (*MovieStatusChanged) Descriptor() ([]byte, []int) {
return file_proto_message_message_proto_rawDescGZIP(), []int{3}
// Deprecated: Use Message.ProtoReflect.Descriptor instead.
func (*Message) Descriptor() ([]byte, []int) {
return file_proto_message_message_proto_rawDescGZIP(), []int{2}
}
func (x *MovieStatusChanged) GetSender() *Sender {
func (x *Message) GetType() MessageType {
if x != nil {
return x.Sender
return x.Type
}
return nil
return MessageType_UNKNOWN
}
func (x *MovieStatusChanged) GetStatus() *MovieStatus {
func (x *Message) GetTimestamp() int64 {
if x != nil {
return x.Status
}
return nil
}
type ElementMessage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Type ElementMessageType `protobuf:"varint,1,opt,name=type,proto3,enum=proto.ElementMessageType" json:"type,omitempty"`
Time int64 `protobuf:"varint,2,opt,name=time,proto3" json:"time,omitempty"`
Error string `protobuf:"bytes,3,opt,name=error,proto3" json:"error,omitempty"`
ChatReq string `protobuf:"bytes,4,opt,name=chatReq,proto3" json:"chatReq,omitempty"`
ChatResp *ChatResp `protobuf:"bytes,5,opt,name=chatResp,proto3" json:"chatResp,omitempty"`
ChangeMovieStatusReq *MovieStatus `protobuf:"bytes,6,opt,name=changeMovieStatusReq,proto3" json:"changeMovieStatusReq,omitempty"`
MovieStatusChanged *MovieStatusChanged `protobuf:"bytes,7,opt,name=movieStatusChanged,proto3" json:"movieStatusChanged,omitempty"`
ChangeSeekReq float64 `protobuf:"fixed64,8,opt,name=changeSeekReq,proto3" json:"changeSeekReq,omitempty"`
CheckStatusReq *MovieStatus `protobuf:"bytes,9,opt,name=checkStatusReq,proto3" json:"checkStatusReq,omitempty"`
ExpireId uint64 `protobuf:"varint,10,opt,name=expireId,proto3" json:"expireId,omitempty"`
PeopleChanged int64 `protobuf:"varint,11,opt,name=peopleChanged,proto3" json:"peopleChanged,omitempty"`
MoviesChanged *Sender `protobuf:"bytes,12,opt,name=moviesChanged,proto3" json:"moviesChanged,omitempty"`
CurrentChanged *Sender `protobuf:"bytes,13,opt,name=currentChanged,proto3" json:"currentChanged,omitempty"`
}
func (x *ElementMessage) Reset() {
*x = ElementMessage{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_message_message_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
return x.Timestamp
}
return 0
}
func (x *ElementMessage) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ElementMessage) ProtoMessage() {}
func (x *ElementMessage) ProtoReflect() protoreflect.Message {
mi := &file_proto_message_message_proto_msgTypes[4]
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 ElementMessage.ProtoReflect.Descriptor instead.
func (*ElementMessage) Descriptor() ([]byte, []int) {
return file_proto_message_message_proto_rawDescGZIP(), []int{4}
}
func (x *ElementMessage) GetType() ElementMessageType {
func (x *Message) GetSender() *Sender {
if x != nil {
return x.Type
return x.Sender
}
return ElementMessageType_UNKNOWN
return nil
}
func (x *ElementMessage) GetTime() int64 {
if x != nil {
return x.Time
func (m *Message) GetPayload() isMessage_Payload {
if m != nil {
return m.Payload
}
return 0
return nil
}
func (x *ElementMessage) GetError() string {
if x != nil {
return x.Error
func (x *Message) GetErrorMessage() string {
if x, ok := x.GetPayload().(*Message_ErrorMessage); ok {
return x.ErrorMessage
}
return ""
}
func (x *ElementMessage) GetChatReq() string {
if x != nil {
return x.ChatReq
func (x *Message) GetChatContent() string {
if x, ok := x.GetPayload().(*Message_ChatContent); ok {
return x.ChatContent
}
return ""
}
func (x *ElementMessage) GetChatResp() *ChatResp {
if x != nil {
return x.ChatResp
func (x *Message) GetPlaybackStatus() *Status {
if x, ok := x.GetPayload().(*Message_PlaybackStatus); ok {
return x.PlaybackStatus
}
return nil
}
func (x *ElementMessage) GetChangeMovieStatusReq() *MovieStatus {
if x != nil {
return x.ChangeMovieStatusReq
func (x *Message) GetExpirationId() uint64 {
if x, ok := x.GetPayload().(*Message_ExpirationId); ok {
return x.ExpirationId
}
return nil
return 0
}
func (x *ElementMessage) GetMovieStatusChanged() *MovieStatusChanged {
if x != nil {
return x.MovieStatusChanged
func (x *Message) GetViewerCount() int64 {
if x, ok := x.GetPayload().(*Message_ViewerCount); ok {
return x.ViewerCount
}
return nil
return 0
}
func (x *ElementMessage) GetChangeSeekReq() float64 {
if x != nil {
return x.ChangeSeekReq
}
return 0
type isMessage_Payload interface {
isMessage_Payload()
}
func (x *ElementMessage) GetCheckStatusReq() *MovieStatus {
if x != nil {
return x.CheckStatusReq
}
return nil
type Message_ErrorMessage struct {
ErrorMessage string `protobuf:"bytes,4,opt,name=error_message,json=errorMessage,proto3,oneof"`
}
func (x *ElementMessage) GetExpireId() uint64 {
if x != nil {
return x.ExpireId
}
return 0
type Message_ChatContent struct {
ChatContent string `protobuf:"bytes,5,opt,name=chat_content,json=chatContent,proto3,oneof"`
}
func (x *ElementMessage) GetPeopleChanged() int64 {
if x != nil {
return x.PeopleChanged
}
return 0
type Message_PlaybackStatus struct {
PlaybackStatus *Status `protobuf:"bytes,6,opt,name=playback_status,json=playbackStatus,proto3,oneof"`
}
func (x *ElementMessage) GetMoviesChanged() *Sender {
if x != nil {
return x.MoviesChanged
}
return nil
type Message_ExpirationId struct {
ExpirationId uint64 `protobuf:"varint,7,opt,name=expiration_id,json=expirationId,proto3,oneof"`
}
func (x *ElementMessage) GetCurrentChanged() *Sender {
if x != nil {
return x.CurrentChanged
}
return nil
type Message_ViewerCount struct {
ViewerCount int64 `protobuf:"varint,8,opt,name=viewer_count,json=viewerCount,proto3,oneof"`
}
func (*Message_ErrorMessage) isMessage_Payload() {}
func (*Message_ChatContent) isMessage_Payload() {}
func (*Message_PlaybackStatus) isMessage_Payload() {}
func (*Message_ExpirationId) isMessage_Payload() {}
func (*Message_ViewerCount) isMessage_Payload() {}
var File_proto_message_message_proto protoreflect.FileDescriptor
var file_proto_message_message_proto_rawDesc = []byte{
0x0a, 0x1b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2f,
0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4b, 0x0a, 0x08, 0x43, 0x68, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70,
0x12, 0x25, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x52,
0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x22, 0x3c, 0x0a, 0x06, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x75,
0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75,
0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x69,
0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x69, 0x64, 0x22,
0x4f, 0x0a, 0x0b, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18,
0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
0x07, 0x70, 0x6c, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x65, 0x6b,
0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x73, 0x65, 0x65, 0x6b, 0x12, 0x12, 0x0a, 0x04,
0x72, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x72, 0x61, 0x74, 0x65,
0x22, 0x67, 0x0a, 0x12, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43,
0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53,
0x65, 0x6e, 0x64, 0x65, 0x72, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x2a, 0x0a,
0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xd3, 0x04, 0x0a, 0x0e, 0x45, 0x6c,
0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2d, 0x0a, 0x04,
0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x2e, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74,
0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12,
0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x74, 0x52, 0x65, 0x71,
0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x74, 0x52, 0x65, 0x71, 0x12,
0x2b, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x68, 0x61, 0x74, 0x52, 0x65,
0x73, 0x70, 0x52, 0x08, 0x63, 0x68, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x46, 0x0a, 0x14,
0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x52, 0x65, 0x71, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x2e, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x14,
0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x52, 0x65, 0x71, 0x12, 0x49, 0x0a, 0x12, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x53, 0x74, 0x61,
0x74, 0x75, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x53, 0x74,
0x61, 0x74, 0x75, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x52, 0x12, 0x6d, 0x6f, 0x76,
0x69, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12,
0x24, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x65, 0x6b, 0x52, 0x65, 0x71,
0x18, 0x08, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0d, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65,
0x65, 0x6b, 0x52, 0x65, 0x71, 0x12, 0x3a, 0x0a, 0x0e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x74,
0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x52, 0x0e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65,
0x71, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x49, 0x64, 0x18, 0x0a, 0x20,
0x01, 0x28, 0x04, 0x52, 0x08, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x49, 0x64, 0x12, 0x24, 0x0a,
0x0d, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x0b,
0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x43, 0x68, 0x61, 0x6e,
0x67, 0x65, 0x64, 0x12, 0x33, 0x0a, 0x0d, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x73, 0x43, 0x68, 0x61,
0x6e, 0x67, 0x65, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x52, 0x0d, 0x6d, 0x6f, 0x76, 0x69, 0x65,
0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x35, 0x0a, 0x0e, 0x63, 0x75, 0x72, 0x72,
0x65, 0x6e, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x52,
0x0e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x2a,
0x9f, 0x02, 0x0a, 0x12, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57,
0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x10,
0x0a, 0x0c, 0x43, 0x48, 0x41, 0x54, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x02,
0x12, 0x08, 0x0a, 0x04, 0x50, 0x4c, 0x41, 0x59, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x41,
0x55, 0x53, 0x45, 0x10, 0x04, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x53,
0x54, 0x41, 0x54, 0x55, 0x53, 0x10, 0x05, 0x12, 0x0c, 0x0a, 0x08, 0x54, 0x4f, 0x4f, 0x5f, 0x46,
0x41, 0x53, 0x54, 0x10, 0x06, 0x12, 0x0c, 0x0a, 0x08, 0x54, 0x4f, 0x4f, 0x5f, 0x53, 0x4c, 0x4f,
0x57, 0x10, 0x07, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x52, 0x41,
0x54, 0x45, 0x10, 0x08, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53,
0x45, 0x45, 0x4b, 0x10, 0x09, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x54,
0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x44, 0x10, 0x0a, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x4f,
0x56, 0x49, 0x45, 0x53, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x44, 0x10, 0x0b, 0x12, 0x12,
0x0a, 0x0e, 0x50, 0x45, 0x4f, 0x50, 0x4c, 0x45, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x44,
0x10, 0x0c, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x4d, 0x4f, 0x56, 0x49, 0x45,
0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x10, 0x0d, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x55, 0x52,
0x52, 0x45, 0x4e, 0x54, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x0e, 0x12, 0x11,
0x0a, 0x0d, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10,
0x0f, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3d, 0x0a, 0x06, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x17,
0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e,
0x61, 0x6d, 0x65, 0x22, 0x6f, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a,
0x0a, 0x69, 0x73, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28,
0x08, 0x52, 0x09, 0x69, 0x73, 0x50, 0x6c, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x12, 0x21, 0x0a, 0x0c,
0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
0x28, 0x01, 0x52, 0x0b, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12,
0x23, 0x0a, 0x0d, 0x70, 0x6c, 0x61, 0x79, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x72, 0x61, 0x74, 0x65,
0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x70, 0x6c, 0x61, 0x79, 0x62, 0x61, 0x63, 0x6b,
0x52, 0x61, 0x74, 0x65, 0x22, 0xe3, 0x02, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x12, 0x26, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79,
0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d,
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72,
0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53,
0x65, 0x6e, 0x64, 0x65, 0x72, 0x48, 0x01, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x88,
0x01, 0x01, 0x12, 0x25, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, 0x65, 0x72, 0x72,
0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x63, 0x68, 0x61,
0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48,
0x00, 0x52, 0x0b, 0x63, 0x68, 0x61, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x38,
0x0a, 0x0f, 0x70, 0x6c, 0x61, 0x79, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75,
0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x0e, 0x70, 0x6c, 0x61, 0x79, 0x62, 0x61,
0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x25, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x69,
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x48,
0x00, 0x52, 0x0c, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12,
0x23, 0x0a, 0x0c, 0x76, 0x69, 0x65, 0x77, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18,
0x08, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x0b, 0x76, 0x69, 0x65, 0x77, 0x65, 0x72, 0x43,
0x6f, 0x75, 0x6e, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x42,
0x09, 0x0a, 0x07, 0x5f, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x2a, 0x9e, 0x01, 0x0a, 0x0b, 0x4d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e,
0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52,
0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x48, 0x41, 0x54, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06,
0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x48, 0x45, 0x43,
0x4b, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x10, 0x04, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x58,
0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x55, 0x52, 0x52, 0x45,
0x4e, 0x54, 0x10, 0x06, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x4f, 0x56, 0x49, 0x45, 0x53, 0x10, 0x07,
0x12, 0x10, 0x0a, 0x0c, 0x56, 0x49, 0x45, 0x57, 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54,
0x10, 0x08, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x59, 0x4e, 0x43, 0x10, 0x09, 0x12, 0x0d, 0x0a, 0x09,
0x4d, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x10, 0x0a, 0x42, 0x06, 0x5a, 0x04, 0x2e,
0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -577,31 +417,22 @@ func file_proto_message_message_proto_rawDescGZIP() []byte {
}
var file_proto_message_message_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_proto_message_message_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_proto_message_message_proto_goTypes = []interface{}{
(ElementMessageType)(0), // 0: proto.ElementMessageType
(*ChatResp)(nil), // 1: proto.ChatResp
(*Sender)(nil), // 2: proto.Sender
(*MovieStatus)(nil), // 3: proto.MovieStatus
(*MovieStatusChanged)(nil), // 4: proto.MovieStatusChanged
(*ElementMessage)(nil), // 5: proto.ElementMessage
var file_proto_message_message_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_proto_message_message_proto_goTypes = []any{
(MessageType)(0), // 0: proto.MessageType
(*Sender)(nil), // 1: proto.Sender
(*Status)(nil), // 2: proto.Status
(*Message)(nil), // 3: proto.Message
}
var file_proto_message_message_proto_depIdxs = []int32{
2, // 0: proto.ChatResp.sender:type_name -> proto.Sender
2, // 1: proto.MovieStatusChanged.sender:type_name -> proto.Sender
3, // 2: proto.MovieStatusChanged.status:type_name -> proto.MovieStatus
0, // 3: proto.ElementMessage.type:type_name -> proto.ElementMessageType
1, // 4: proto.ElementMessage.chatResp:type_name -> proto.ChatResp
3, // 5: proto.ElementMessage.changeMovieStatusReq:type_name -> proto.MovieStatus
4, // 6: proto.ElementMessage.movieStatusChanged:type_name -> proto.MovieStatusChanged
3, // 7: proto.ElementMessage.checkStatusReq:type_name -> proto.MovieStatus
2, // 8: proto.ElementMessage.moviesChanged:type_name -> proto.Sender
2, // 9: proto.ElementMessage.currentChanged:type_name -> proto.Sender
10, // [10:10] is the sub-list for method output_type
10, // [10:10] is the sub-list for method input_type
10, // [10:10] is the sub-list for extension type_name
10, // [10:10] is the sub-list for extension extendee
0, // [0:10] is the sub-list for field type_name
0, // 0: proto.Message.type:type_name -> proto.MessageType
1, // 1: proto.Message.sender:type_name -> proto.Sender
2, // 2: proto.Message.playback_status:type_name -> proto.Status
3, // [3:3] is the sub-list for method output_type
3, // [3:3] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
}
func init() { file_proto_message_message_proto_init() }
@ -609,67 +440,12 @@ func file_proto_message_message_proto_init() {
if File_proto_message_message_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_proto_message_message_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ChatResp); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_message_message_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Sender); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_message_message_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MovieStatus); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_message_message_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MovieStatusChanged); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_message_message_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ElementMessage); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_message_message_proto_msgTypes[2].OneofWrappers = []any{
(*Message_ErrorMessage)(nil),
(*Message_ChatContent)(nil),
(*Message_PlaybackStatus)(nil),
(*Message_ExpirationId)(nil),
(*Message_ViewerCount)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{
@ -677,7 +453,7 @@ func file_proto_message_message_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_message_message_proto_rawDesc,
NumEnums: 1,
NumMessages: 5,
NumMessages: 3,
NumExtensions: 0,
NumServices: 0,
},

@ -3,58 +3,41 @@ option go_package = ".;pb";
package proto;
enum ElementMessageType {
enum MessageType {
UNKNOWN = 0;
ERROR = 1;
CHAT_MESSAGE = 2;
PLAY = 3;
PAUSE = 4;
CHECK_STATUS = 5;
TOO_FAST = 6;
TOO_SLOW = 7;
CHANGE_RATE = 8;
CHANGE_SEEK = 9;
CURRENT_CHANGED = 10;
MOVIES_CHANGED = 11;
PEOPLE_CHANGED = 12;
SYNC_MOVIE_STATUS = 13;
CURRENT_EXPIRED = 14;
CHECK_EXPIRED = 15;
}
message ChatResp {
Sender sender = 1;
string message = 2;
CHAT = 2;
STATUS = 3;
CHECK_STATUS = 4;
EXPIRED = 5;
CURRENT = 6;
MOVIES = 7;
VIEWER_COUNT = 8;
SYNC = 9;
MY_STATUS = 10;
}
message Sender {
string username = 1;
string userid = 2;
string user_id = 1;
string username = 2;
}
message MovieStatus {
bool playing = 1;
double seek = 2;
double rate = 3;
message Status {
bool is_playing = 1;
double current_time = 2;
double playback_rate = 3;
}
message MovieStatusChanged {
Sender sender = 1;
MovieStatus status = 2;
}
message Message {
MessageType type = 1;
int64 timestamp = 2;
optional Sender sender = 3;
message ElementMessage {
ElementMessageType type = 1;
int64 time = 2;
string error = 3;
string chatReq = 4;
ChatResp chatResp = 5;
MovieStatus changeMovieStatusReq = 6;
MovieStatusChanged movieStatusChanged = 7;
double changeSeekReq = 8;
MovieStatus checkStatusReq = 9;
uint64 expireId = 10;
int64 peopleChanged = 11;
Sender moviesChanged = 12;
Sender currentChanged = 13;
}
oneof payload {
string error_message = 4;
string chat_content = 5;
Status playback_status = 6;
uint64 expiration_id = 7;
int64 viewer_count = 8;
}
}

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.34.1
// protoc v5.26.1
// protoc-gen-go v1.35.1
// protoc v5.28.2
// source: proto/provider/plugin.proto
package providerpb
@ -32,11 +32,9 @@ type InitReq struct {
func (x *InitReq) Reset() {
*x = InitReq{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_proto_provider_plugin_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *InitReq) String() string {
@ -47,7 +45,7 @@ func (*InitReq) ProtoMessage() {}
func (x *InitReq) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -93,11 +91,9 @@ type GetTokenReq struct {
func (x *GetTokenReq) Reset() {
*x = GetTokenReq{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_proto_provider_plugin_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetTokenReq) String() string {
@ -108,7 +104,7 @@ func (*GetTokenReq) ProtoMessage() {}
func (x *GetTokenReq) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -140,11 +136,9 @@ type RefreshTokenReq struct {
func (x *RefreshTokenReq) Reset() {
*x = RefreshTokenReq{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_proto_provider_plugin_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RefreshTokenReq) String() string {
@ -155,7 +149,7 @@ func (*RefreshTokenReq) ProtoMessage() {}
func (x *RefreshTokenReq) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -187,11 +181,9 @@ type ProviderResp struct {
func (x *ProviderResp) Reset() {
*x = ProviderResp{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_proto_provider_plugin_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ProviderResp) String() string {
@ -202,7 +194,7 @@ func (*ProviderResp) ProtoMessage() {}
func (x *ProviderResp) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -234,11 +226,9 @@ type NewAuthURLReq struct {
func (x *NewAuthURLReq) Reset() {
*x = NewAuthURLReq{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_proto_provider_plugin_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *NewAuthURLReq) String() string {
@ -249,7 +239,7 @@ func (*NewAuthURLReq) ProtoMessage() {}
func (x *NewAuthURLReq) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -281,11 +271,9 @@ type NewAuthURLResp struct {
func (x *NewAuthURLResp) Reset() {
*x = NewAuthURLResp{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_proto_provider_plugin_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *NewAuthURLResp) String() string {
@ -296,7 +284,7 @@ func (*NewAuthURLResp) ProtoMessage() {}
func (x *NewAuthURLResp) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -328,11 +316,9 @@ type GetUserInfoReq struct {
func (x *GetUserInfoReq) Reset() {
*x = GetUserInfoReq{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_proto_provider_plugin_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetUserInfoReq) String() string {
@ -343,7 +329,7 @@ func (*GetUserInfoReq) ProtoMessage() {}
func (x *GetUserInfoReq) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -376,11 +362,9 @@ type GetUserInfoResp struct {
func (x *GetUserInfoResp) Reset() {
*x = GetUserInfoResp{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_proto_provider_plugin_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetUserInfoResp) String() string {
@ -391,7 +375,7 @@ func (*GetUserInfoResp) ProtoMessage() {}
func (x *GetUserInfoResp) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -428,11 +412,9 @@ type Enpty struct {
func (x *Enpty) Reset() {
*x = Enpty{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_provider_plugin_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
mi := &file_proto_provider_plugin_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Enpty) String() string {
@ -443,7 +425,7 @@ func (*Enpty) ProtoMessage() {}
func (x *Enpty) ProtoReflect() protoreflect.Message {
mi := &file_proto_provider_plugin_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
@ -523,7 +505,7 @@ func file_proto_provider_plugin_proto_rawDescGZIP() []byte {
}
var file_proto_provider_plugin_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_proto_provider_plugin_proto_goTypes = []interface{}{
var file_proto_provider_plugin_proto_goTypes = []any{
(*InitReq)(nil), // 0: proto.InitReq
(*GetTokenReq)(nil), // 1: proto.GetTokenReq
(*RefreshTokenReq)(nil), // 2: proto.RefreshTokenReq
@ -555,116 +537,6 @@ func file_proto_provider_plugin_proto_init() {
if File_proto_provider_plugin_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_proto_provider_plugin_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*InitReq); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_provider_plugin_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetTokenReq); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_provider_plugin_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RefreshTokenReq); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_provider_plugin_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ProviderResp); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_provider_plugin_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NewAuthURLReq); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_provider_plugin_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NewAuthURLResp); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_provider_plugin_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetUserInfoReq); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_provider_plugin_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetUserInfoResp); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_provider_plugin_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Enpty); 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{
File: protoimpl.DescBuilder{

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc v5.26.1
// - protoc-gen-go-grpc v1.5.1
// - protoc v5.28.2
// source: proto/provider/plugin.proto
package providerpb
@ -15,8 +15,8 @@ import (
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// Requires gRPC-Go v1.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
Oauth2Plugin_Init_FullMethodName = "/proto.Oauth2Plugin/Init"
@ -44,8 +44,9 @@ func NewOauth2PluginClient(cc grpc.ClientConnInterface) Oauth2PluginClient {
}
func (c *oauth2PluginClient) Init(ctx context.Context, in *InitReq, opts ...grpc.CallOption) (*Enpty, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(Enpty)
err := c.cc.Invoke(ctx, Oauth2Plugin_Init_FullMethodName, in, out, opts...)
err := c.cc.Invoke(ctx, Oauth2Plugin_Init_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
@ -53,8 +54,9 @@ func (c *oauth2PluginClient) Init(ctx context.Context, in *InitReq, opts ...grpc
}
func (c *oauth2PluginClient) Provider(ctx context.Context, in *Enpty, opts ...grpc.CallOption) (*ProviderResp, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ProviderResp)
err := c.cc.Invoke(ctx, Oauth2Plugin_Provider_FullMethodName, in, out, opts...)
err := c.cc.Invoke(ctx, Oauth2Plugin_Provider_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
@ -62,8 +64,9 @@ func (c *oauth2PluginClient) Provider(ctx context.Context, in *Enpty, opts ...gr
}
func (c *oauth2PluginClient) NewAuthURL(ctx context.Context, in *NewAuthURLReq, opts ...grpc.CallOption) (*NewAuthURLResp, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(NewAuthURLResp)
err := c.cc.Invoke(ctx, Oauth2Plugin_NewAuthURL_FullMethodName, in, out, opts...)
err := c.cc.Invoke(ctx, Oauth2Plugin_NewAuthURL_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
@ -71,8 +74,9 @@ func (c *oauth2PluginClient) NewAuthURL(ctx context.Context, in *NewAuthURLReq,
}
func (c *oauth2PluginClient) GetUserInfo(ctx context.Context, in *GetUserInfoReq, opts ...grpc.CallOption) (*GetUserInfoResp, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GetUserInfoResp)
err := c.cc.Invoke(ctx, Oauth2Plugin_GetUserInfo_FullMethodName, in, out, opts...)
err := c.cc.Invoke(ctx, Oauth2Plugin_GetUserInfo_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
@ -81,7 +85,7 @@ func (c *oauth2PluginClient) GetUserInfo(ctx context.Context, in *GetUserInfoReq
// Oauth2PluginServer is the server API for Oauth2Plugin service.
// All implementations must embed UnimplementedOauth2PluginServer
// for forward compatibility
// for forward compatibility.
type Oauth2PluginServer interface {
Init(context.Context, *InitReq) (*Enpty, error)
Provider(context.Context, *Enpty) (*ProviderResp, error)
@ -90,9 +94,12 @@ type Oauth2PluginServer interface {
mustEmbedUnimplementedOauth2PluginServer()
}
// UnimplementedOauth2PluginServer must be embedded to have forward compatible implementations.
type UnimplementedOauth2PluginServer struct {
}
// UnimplementedOauth2PluginServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedOauth2PluginServer struct{}
func (UnimplementedOauth2PluginServer) Init(context.Context, *InitReq) (*Enpty, error) {
return nil, status.Errorf(codes.Unimplemented, "method Init not implemented")
@ -107,6 +114,7 @@ func (UnimplementedOauth2PluginServer) GetUserInfo(context.Context, *GetUserInfo
return nil, status.Errorf(codes.Unimplemented, "method GetUserInfo not implemented")
}
func (UnimplementedOauth2PluginServer) mustEmbedUnimplementedOauth2PluginServer() {}
func (UnimplementedOauth2PluginServer) testEmbeddedByValue() {}
// UnsafeOauth2PluginServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to Oauth2PluginServer will
@ -116,6 +124,13 @@ type UnsafeOauth2PluginServer interface {
}
func RegisterOauth2PluginServer(s grpc.ServiceRegistrar, srv Oauth2PluginServer) {
// If the following call pancis, it indicates UnimplementedOauth2PluginServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&Oauth2Plugin_ServiceDesc, srv)
}

@ -8,7 +8,6 @@ import (
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"github.com/sirupsen/logrus"
log "github.com/sirupsen/logrus"
dbModel "github.com/synctv-org/synctv/internal/model"
"github.com/synctv-org/synctv/internal/op"
@ -17,242 +16,282 @@ import (
"google.golang.org/protobuf/proto"
)
const maxInterval = 10
const (
maxInterval = 10
MaxChatMessageLength = 4096
)
func NewWebSocketHandler(wss *utils.WebSocket) gin.HandlerFunc {
return func(ctx *gin.Context) {
subprotocols := []string{}
token := ctx.MustGet("token").(string)
room := ctx.MustGet("room").(*op.RoomEntry).Value()
user := ctx.MustGet("user").(*op.UserEntry).Value()
log := ctx.MustGet("log").(*log.Entry)
subprotocols := []string{}
if token != "" {
subprotocols = append(subprotocols, token)
}
room := ctx.MustGet("room").(*op.RoomEntry).Value()
user := ctx.MustGet("user").(*op.UserEntry).Value()
log := ctx.MustGet("log").(*logrus.Entry)
_ = wss.Server(ctx.Writer, ctx.Request, subprotocols, NewWSMessageHandler(user, room, log))
}
}
func NewWSMessageHandler(u *op.User, r *op.Room, l *logrus.Entry) func(c *websocket.Conn) error {
func NewWSMessageHandler(u *op.User, r *op.Room, l *log.Entry) func(c *websocket.Conn) error {
return func(c *websocket.Conn) error {
client, err := r.NewClient(u, c)
if err != nil {
log.Errorf("ws: register client error: %v", err)
l.Errorf("ws: register client error: %v", err)
wc, err2 := c.NextWriter(websocket.BinaryMessage)
if err2 != nil {
return err2
}
defer wc.Close()
em := pb.ElementMessage{
Type: pb.ElementMessageType_ERROR,
Error: err.Error(),
em := pb.Message{
Type: pb.MessageType_ERROR,
Payload: &pb.Message_ErrorMessage{
ErrorMessage: fmt.Sprintf("register client error: %v", err),
},
}
return em.Encode(wc)
}
l.Info("ws: connected")
defer func() {
_ = r.UnregisterClient(client)
client.Close()
l.Info("ws: disconnected")
}()
if err := client.Send(&pb.ElementMessage{
Type: pb.ElementMessageType_PEOPLE_CHANGED,
PeopleChanged: r.PeopleNum(),
}); err != nil {
l.Errorf("ws: send people changed error: %v", err)
defer handleClientDisconnection(r, client, l)
if err := sendViewerCount(client, r); err != nil {
l.Errorf("ws: send viewer count error: %v", err)
return err
}
go handleReaderMessage(client, l)
return handleWriterMessage(client, l)
}
}
func handleWriterMessage(c *op.Client, l *logrus.Entry) error {
func handleClientDisconnection(r *op.Room, client *op.Client, l *log.Entry) {
if err := r.UnregisterClient(client); err != nil {
l.Errorf("ws: unregister client error: %v", err)
}
client.Close()
l.Info("ws: disconnected")
}
func sendViewerCount(client *op.Client, r *op.Room) error {
return client.Send(&pb.Message{
Type: pb.MessageType_VIEWER_COUNT,
Payload: &pb.Message_ViewerCount{
ViewerCount: r.PeopleNum(),
},
})
}
func handleWriterMessage(c *op.Client, l *log.Entry) error {
for v := range c.GetReadChan() {
wc, err := c.NextWriter(v.MessageType())
if err != nil {
l.Errorf("ws: get next writer error: %v", err)
if err := writeMessage(c, v); err != nil {
l.Errorf("ws: write message error: %v", err)
return err
}
}
return nil
}
if err = v.Encode(wc); err != nil {
l.Errorf("ws: encode message error: %v", err)
return err
}
func writeMessage(c *op.Client, v op.Message) error {
wc, err := c.NextWriter(v.MessageType())
if err != nil {
return fmt.Errorf("get next writer error: %w", err)
}
defer wc.Close()
if err = wc.Close(); err != nil {
l.Errorf("ws: close writer error: %v", err)
return err
}
if err = v.Encode(wc); err != nil {
return fmt.Errorf("encode message error: %w", err)
}
return nil
}
func handleReaderMessage(c *op.Client, l *logrus.Entry) error {
func handleReaderMessage(c *op.Client, l *log.Entry) error {
defer func() {
c.Close()
if r := recover(); r != nil {
l.Errorf("ws: panic: %v", r)
}
}()
for {
t, rd, err := c.NextReader()
msg, err := readMessage(c)
if err != nil {
l.Errorf("ws: get next reader error: %v", err)
return err
}
l.Debugf("ws: receive message type: %d", t)
if t != websocket.BinaryMessage {
l.Errorf("ws: receive unknown message type: %d", t)
continue
}
var data []byte
if data, err = io.ReadAll(rd); err != nil {
l.Errorf("ws: read message error: %v", err)
if err := c.Send(&pb.ElementMessage{
Type: pb.ElementMessageType_ERROR,
Error: err.Error(),
}); err != nil {
l.Errorf("ws: send error message error: %v", err)
return err
}
continue
}
var msg pb.ElementMessage
if err := proto.Unmarshal(data, &msg); err != nil {
l.Errorf("ws: unmarshal message error: %v", err)
if err := c.Send(&pb.ElementMessage{
Type: pb.ElementMessageType_ERROR,
Error: err.Error(),
}); err != nil {
l.Errorf("ws: send error message error: %v", err)
return err
}
continue
return err
}
l.Debugf("ws: receive message: %v", msg.String())
if err = handleElementMsg(c, &msg); err != nil {
if err = handleElementMsg(c, msg); err != nil {
l.Errorf("ws: handle message error: %v", err)
return err
}
}
}
const MaxChatMessageLength = 4096
func readMessage(c *op.Client) (*pb.Message, error) {
t, rd, err := c.NextReader()
if err != nil {
return nil, fmt.Errorf("get next reader error: %w", err)
}
if t != websocket.BinaryMessage {
return nil, fmt.Errorf("receive unknown message type: %d", t)
}
func handleElementMsg(cli *op.Client, msg *pb.ElementMessage) error {
var timeDiff float64
if msg.Time != 0 {
timeDiff = time.Since(time.UnixMilli(msg.Time)).Seconds()
} else {
timeDiff = 0.0
data, err := io.ReadAll(rd)
if err != nil {
return nil, fmt.Errorf("read message error: %w", err)
}
if timeDiff < 0 {
timeDiff = 0
} else if timeDiff > 1.5 {
timeDiff = 1.5
var msg pb.Message
if err := proto.Unmarshal(data, &msg); err != nil {
return nil, fmt.Errorf("unmarshal message error: %w", err)
}
return &msg, nil
}
func handleElementMsg(cli *op.Client, msg *pb.Message) error {
timeDiff := calculateTimeDiff(msg.Timestamp)
switch msg.Type {
case pb.ElementMessageType_CHAT_MESSAGE:
message := msg.GetChatReq()
if len(message) > MaxChatMessageLength {
return cli.Send(&pb.ElementMessage{
Type: pb.ElementMessageType_ERROR,
Error: "message too long",
})
}
err := cli.SendChatMessage(message)
if err != nil && errors.Is(err, dbModel.ErrNoPermission) {
return cli.Send(&pb.ElementMessage{
Type: pb.ElementMessageType_ERROR,
Error: fmt.Sprintf("send chat message error: %v", err),
})
}
return err
case pb.ElementMessageType_PLAY,
pb.ElementMessageType_PAUSE,
pb.ElementMessageType_CHANGE_SEEK,
pb.ElementMessageType_CHANGE_RATE:
status, err := cli.SetStatus(msg.ChangeMovieStatusReq.Playing, msg.ChangeMovieStatusReq.Seek, msg.ChangeMovieStatusReq.Rate, timeDiff)
if err != nil {
return cli.Send(&pb.ElementMessage{
Type: pb.ElementMessageType_ERROR,
Error: fmt.Sprintf("set status error: %v", err),
})
}
return cli.Broadcast(&pb.ElementMessage{
Type: msg.Type,
MovieStatusChanged: &pb.MovieStatusChanged{
Sender: &pb.Sender{
Username: cli.User().Username,
Userid: cli.User().ID,
},
Status: &pb.MovieStatus{
Playing: status.Playing,
Seek: status.Seek,
Rate: status.Rate,
},
},
}, op.WithIgnoreClient(cli))
case pb.ElementMessageType_SYNC_MOVIE_STATUS:
status := cli.Room().Current().Status
return cli.Send(&pb.ElementMessage{
Type: pb.ElementMessageType_SYNC_MOVIE_STATUS,
MovieStatusChanged: &pb.MovieStatusChanged{
Sender: &pb.Sender{
Username: cli.User().Username,
Userid: cli.User().ID,
},
Status: &pb.MovieStatus{
Playing: status.Playing,
Seek: status.Seek,
Rate: status.Rate,
},
case pb.MessageType_CHAT:
return handleChatMessage(cli, msg.GetChatContent())
case pb.MessageType_STATUS:
return handleStatusMessage(cli, msg, timeDiff)
case pb.MessageType_SYNC:
return handleSyncMessage(cli)
case pb.MessageType_EXPIRED:
return handleExpiredMessage(cli, msg.GetExpirationId())
case pb.MessageType_CHECK_STATUS:
return handleCheckStatusMessage(cli, msg, timeDiff)
default:
return sendErrorMessage(cli, fmt.Sprintf("unknown message type: %v", msg.Type))
}
}
func calculateTimeDiff(timestamp int64) float64 {
if timestamp == 0 {
return 0.0
}
timeDiff := time.Since(time.UnixMilli(timestamp)).Seconds()
if timeDiff < 0 {
return 0
}
if timeDiff > 1.5 {
return 1.5
}
return timeDiff
}
func handleChatMessage(cli *op.Client, message string) error {
if message == "" {
return sendErrorMessage(cli, "message is empty")
}
if len(message) > MaxChatMessageLength {
return sendErrorMessage(cli, "message too long")
}
err := cli.SendChatMessage(message)
if err != nil && errors.Is(err, dbModel.ErrNoPermission) {
return sendErrorMessage(cli, fmt.Sprintf("send chat message error: %v", err))
}
return err
}
func handleStatusMessage(cli *op.Client, msg *pb.Message, timeDiff float64) error {
playbackStatus := msg.GetPlaybackStatus()
if playbackStatus == nil {
return sendErrorMessage(cli, "playback status is nil")
}
err := cli.SetStatus(
playbackStatus.GetIsPlaying(),
playbackStatus.GetCurrentTime(),
playbackStatus.GetPlaybackRate(),
timeDiff,
)
if err != nil {
return sendErrorMessage(cli, fmt.Sprintf("set status error: %v", err))
}
return nil
}
func handleSyncMessage(cli *op.Client) error {
status := cli.Room().Current().Status
return cli.Send(&pb.Message{
Type: pb.MessageType_SYNC,
Timestamp: time.Now().UnixMilli(),
Payload: &pb.Message_PlaybackStatus{
PlaybackStatus: &pb.Status{
IsPlaying: status.IsPlaying,
CurrentTime: status.CurrentTime,
PlaybackRate: status.PlaybackRate,
},
})
case pb.ElementMessageType_CHECK_EXPIRED:
current := cli.Room().Current()
if msg.ExpireId != 0 && current.Movie.ID != "" {
currentMovie, err := cli.Room().GetMovieByID(current.Movie.ID)
if err != nil {
return cli.Send(&pb.ElementMessage{
Type: pb.ElementMessageType_ERROR,
Error: fmt.Sprintf("get movie by id error: %v", err),
})
}
if currentMovie.CheckExpired(msg.ExpireId) {
return cli.Send(&pb.ElementMessage{
Type: pb.ElementMessageType_CURRENT_EXPIRED,
})
}
},
})
}
func handleExpiredMessage(cli *op.Client, expirationId uint64) error {
current := cli.Room().Current()
if expirationId != 0 && current.Movie.ID != "" {
currentMovie, err := cli.Room().GetMovieByID(current.Movie.ID)
if err != nil {
return sendErrorMessage(cli, fmt.Sprintf("get movie by id error: %v", err))
}
case pb.ElementMessageType_CHECK_STATUS:
current := cli.Room().Current()
status := current.Status
if status.Seek+maxInterval < msg.CheckStatusReq.Seek+timeDiff {
return cli.Send(&pb.ElementMessage{
Type: pb.ElementMessageType_TOO_FAST,
MovieStatusChanged: &pb.MovieStatusChanged{
Status: &pb.MovieStatus{
Playing: status.Playing,
Seek: status.Seek,
Rate: status.Rate,
},
},
})
} else if status.Seek-maxInterval > msg.CheckStatusReq.Seek+timeDiff {
return cli.Send(&pb.ElementMessage{
Type: pb.ElementMessageType_TOO_SLOW,
MovieStatusChanged: &pb.MovieStatusChanged{
Status: &pb.MovieStatus{
Playing: status.Playing,
Seek: status.Seek,
Rate: status.Rate,
},
},
if currentMovie.CheckExpired(expirationId) {
return cli.Send(&pb.Message{
Type: pb.MessageType_EXPIRED,
})
}
}
return nil
}
func handleCheckStatusMessage(cli *op.Client, msg *pb.Message, timeDiff float64) error {
current := cli.Room().Current()
status := current.Status
cliStatus := msg.GetPlaybackStatus()
if cliStatus == nil {
return sendErrorMessage(cli, "playback status is nil")
}
if needsSync(cliStatus, status, timeDiff) {
return sendSyncStatus(cli, &status)
}
return nil
}
func needsSync(clientStatus *pb.Status, serverStatus op.Status, timeDiff float64) bool {
if clientStatus.IsPlaying != serverStatus.IsPlaying ||
clientStatus.PlaybackRate != serverStatus.PlaybackRate ||
serverStatus.CurrentTime+maxInterval < clientStatus.CurrentTime+timeDiff ||
serverStatus.CurrentTime-maxInterval > clientStatus.CurrentTime+timeDiff {
return true
}
return false
}
func sendErrorMessage(c *op.Client, errorMsg string) error {
return c.Send(&pb.Message{
Type: pb.MessageType_ERROR,
Payload: &pb.Message_ErrorMessage{
ErrorMessage: errorMsg,
},
})
}
func sendSyncStatus(cli *op.Client, status *op.Status) error {
return cli.Send(&pb.Message{
Type: pb.MessageType_CHECK_STATUS,
Payload: &pb.Message_PlaybackStatus{
PlaybackStatus: &pb.Status{
IsPlaying: status.IsPlaying,
CurrentTime: status.CurrentTime,
PlaybackRate: status.PlaybackRate,
},
},
})
}

Loading…
Cancel
Save