diff --git a/.github/workflows/release_docker.yml b/.github/workflows/release_docker.yml index 555606e..36da889 100644 --- a/.github/workflows/release_docker.yml +++ b/.github/workflows/release_docker.yml @@ -6,7 +6,7 @@ on: - "v*" jobs: - release_docker: + build: name: Release Docker runs-on: ubuntu-latest strategy: @@ -39,9 +39,11 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Get version - id: get_version - run: echo "VERSION=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_OUTPUT + - name: Prepare + id: prepare + run: | + echo "VERSION=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_OUTPUT + echo "TARFILE=${platforms//\//-}.tar" >> $GITHUB_OUTPUT - name: Build and push id: docker_build @@ -49,8 +51,58 @@ jobs: with: context: . build-args: - VERSION=v${{ steps.get_version.outputs.VERSION }} - push: true + VERSION=v${{ steps.prepare.outputs.VERSION }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} platforms: ${{ matrix.platforms }} + outputs: type=docker,dest=/tmp/images/${{ steps.prepare.outputs.TARFILE }} + + - name: Upload image + uses: actions/upload-artifact@v4 + with: + name: images + path: /tmp/images/${{ steps.prepare.outputs.TARFILE }} + if-no-files-found: error + retention-days: 1 + + push: + runs-on: ubuntu-latest + needs: + - build + services: + registry: + image: registry:2 + ports: + - 5000:5000 + steps: + - + name: Download images + uses: actions/download-artifact@v3 + with: + name: images + path: /tmp/images + - + name: Load images + run: | + for image in /tmp/images/*.tar; do + docker load -i $image + done + - + name: Push images to local registry + run: | + docker push -a ${{ env.TMP_LOCAL_IMAGE }} + - + name: Login to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - + name: Create manifest list and push + run: | + docker buildx imagetools create -t ${{ env.REGISTRY_IMAGE }}:${{ env.REGISTRY_TAG }} \ + $(docker image ls --format '{{.Repository}}:{{.Tag}}' '${{ env.TMP_LOCAL_IMAGE }}' | tr '\n' ' ') + - + name: Inspect image + run: | + docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ env.REGISTRY_TAG }} \ No newline at end of file diff --git a/go.mod b/go.mod index bee80b6..b6c831c 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/synctv-org/vendors v0.3.2 github.com/ulule/limiter/v3 v3.11.2 github.com/zencoder/go-dash/v3 v3.0.3 - github.com/zijiren233/gencontainer v0.0.0-20240108151314-9632e4fe47e7 + github.com/zijiren233/gencontainer v0.0.0-20240129140900-d43d1aa9cf73 github.com/zijiren233/go-colorable v0.0.0-20230930131441-997304c961cb github.com/zijiren233/livelib v0.3.1 github.com/zijiren233/stream v0.5.1 diff --git a/go.sum b/go.sum index 59b3b04..0d96856 100644 --- a/go.sum +++ b/go.sum @@ -358,6 +358,8 @@ github.com/zencoder/go-dash/v3 v3.0.3 h1:xqwGJ2fJCSArwONGx6sY26Z1lxQ7zTURoxdRjCp github.com/zencoder/go-dash/v3 v3.0.3/go.mod h1:30R5bKy1aUYY45yesjtZ9l8trNc2TwNqbS17WVQmCzk= github.com/zijiren233/gencontainer v0.0.0-20240108151314-9632e4fe47e7 h1:oXWgG6iEZ8MbZr0WkPT/8WAcLguxnhdRT96JwyFXHZE= github.com/zijiren233/gencontainer v0.0.0-20240108151314-9632e4fe47e7/go.mod h1:V5oL7PrZxgisuLCblFWd89Jg99O8vM1n58llcxZ2hDY= +github.com/zijiren233/gencontainer v0.0.0-20240129140900-d43d1aa9cf73 h1:yuqmOc7chu/SdynYEFdHLH8X3E7ziFmP42auRljMwCU= +github.com/zijiren233/gencontainer v0.0.0-20240129140900-d43d1aa9cf73/go.mod h1:V5oL7PrZxgisuLCblFWd89Jg99O8vM1n58llcxZ2hDY= github.com/zijiren233/go-colorable v0.0.0-20230930131441-997304c961cb h1:0DyOxf/TbbGodHhOVHNoPk+7v/YBJACs22gKpKlatWw= github.com/zijiren233/go-colorable v0.0.0-20230930131441-997304c961cb/go.mod h1:6TCzjDiQ8+5gWZiwsC3pnA5M0vUy2jV2Y7ciHJh729g= github.com/zijiren233/livelib v0.3.0 h1:RLfx6vSUr7wfK6F0VY0aFOBDcT/ljvjQUTOlHEcUlUQ= diff --git a/internal/op/hub.go b/internal/op/hub.go index d94f47a..e065980 100644 --- a/internal/op/hub.go +++ b/internal/op/hub.go @@ -107,9 +107,9 @@ func (h *Hub) ping() { case <-ticker.C: current = h.PeopleNum() if current != pre { - if err := h.Broadcast(&ElementMessage{ - Type: pb.ElementMessageType_CHANGE_PEOPLE, - PeopleNum: current, + if err := h.Broadcast(&pb.ElementMessage{ + Type: pb.ElementMessageType_PEOPLE_CHANGED, + PeopleChanged: current, }); err != nil { continue } diff --git a/internal/op/message.go b/internal/op/message.go index 38403e0..af0e43a 100644 --- a/internal/op/message.go +++ b/internal/op/message.go @@ -4,8 +4,6 @@ import ( "io" "github.com/gorilla/websocket" - pb "github.com/synctv-org/synctv/proto/message" - "google.golang.org/protobuf/proto" ) type Message interface { @@ -14,25 +12,6 @@ type Message interface { Encode(w io.Writer) error } -type ElementMessage pb.ElementMessage - -func (em *ElementMessage) MessageType() int { - return websocket.BinaryMessage -} - -func (em *ElementMessage) String() string { - return (*pb.ElementMessage)(em).String() -} - -func (em *ElementMessage) Encode(w io.Writer) error { - b, err := proto.Marshal((*pb.ElementMessage)(em)) - if err != nil { - return err - } - _, err = w.Write(b) - return err -} - type PingMessage struct{} func (pm *PingMessage) MessageType() int { diff --git a/internal/op/movie.go b/internal/op/movie.go index eeb2db9..7ca2102 100644 --- a/internal/op/movie.go +++ b/internal/op/movie.go @@ -3,11 +3,13 @@ package op import ( "errors" "fmt" + "hash/crc32" "net/url" "sync/atomic" "time" "github.com/go-resty/resty/v2" + "github.com/sirupsen/logrus" "github.com/synctv-org/synctv/internal/cache" "github.com/synctv-org/synctv/internal/conf" "github.com/synctv-org/synctv/internal/model" @@ -22,13 +24,35 @@ import ( ) type Movie struct { - Movie model.Movie + model.Movie channel atomic.Pointer[rtmps.Channel] alistCache atomic.Pointer[cache.AlistMovieCache] bilibiliCache atomic.Pointer[cache.BilibiliMovieCache] embyCache atomic.Pointer[cache.EmbyMovieCache] } +func (m *Movie) ExpireId() uint64 { + switch { + default: + return uint64(crc32.ChecksumIEEE([]byte(m.Movie.ID))) + case m.Movie.Base.VendorInfo.Vendor == model.VendorAlist && + len(m.AlistCache().Raw().AliM3U8ListFile) != 0: + return uint64(m.AlistCache().Last()) + } +} + +func (m *Movie) CheckExpired(expireId uint64) bool { + switch { + default: + return expireId != m.ExpireId() + case m.Movie.Base.VendorInfo.Vendor == model.VendorAlist && + len(m.AlistCache().Raw().AliM3U8ListFile) != 0: + logrus.Info(expireId) + logrus.Info(time.Now().UnixNano()) + return time.Now().UnixNano()-int64(expireId) > m.AlistCache().MaxAge() + } +} + func (m *Movie) ClearCache() { m.alistCache.Store(nil) diff --git a/internal/op/room.go b/internal/op/room.go index 8831a03..6d37c5e 100644 --- a/internal/op/room.go +++ b/internal/op/room.go @@ -180,6 +180,18 @@ func (r *Room) Current() *Current { return &c } +func (r *Room) CurrentMovie() (*Movie, error) { + return r.GetMovieByID(r.current.current.Movie.ID) +} + +func (r *Room) CheckCurrentExpired(expireId uint64) (bool, error) { + m, err := r.CurrentMovie() + if err != nil { + return false, err + } + return m.CheckExpired(expireId), nil +} + func (r *Room) SetCurrentMovieByID(id string, play bool) error { m, err := r.movies.GetMovieByID(id) if err != nil { diff --git a/proto/message/message.go b/proto/message/message.go new file mode 100644 index 0000000..0d97389 --- /dev/null +++ b/proto/message/message.go @@ -0,0 +1,21 @@ +package pb + +import ( + "io" + + "github.com/gorilla/websocket" + "google.golang.org/protobuf/proto" +) + +func (em *ElementMessage) MessageType() int { + return websocket.BinaryMessage +} + +func (em *ElementMessage) Encode(w io.Writer) error { + b, err := proto.Marshal((*ElementMessage)(em)) + if err != nil { + return err + } + _, err = w.Write(b) + return err +} diff --git a/proto/message/message.pb.go b/proto/message/message.pb.go index 533aeef..2e16bcc 100644 --- a/proto/message/message.pb.go +++ b/proto/message/message.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 -// protoc v4.25.1 +// protoc-gen-go v1.32.0 +// protoc v4.25.2 // source: proto/message/message.proto package pb @@ -23,19 +23,19 @@ const ( type ElementMessageType 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_SEEK ElementMessageType = 5 - ElementMessageType_TOO_FAST ElementMessageType = 6 - ElementMessageType_TOO_SLOW ElementMessageType = 7 - ElementMessageType_CHANGE_RATE ElementMessageType = 8 - ElementMessageType_CHANGE_SEEK ElementMessageType = 9 - ElementMessageType_CHANGE_CURRENT ElementMessageType = 10 - ElementMessageType_CHANGE_MOVIES ElementMessageType = 11 - ElementMessageType_CHANGE_PEOPLE ElementMessageType = 12 + ElementMessageType_UNKNOWN ElementMessageType = 0 + ElementMessageType_ERROR ElementMessageType = 1 + ElementMessageType_CHAT_MESSAGE ElementMessageType = 2 + ElementMessageType_PLAY ElementMessageType = 3 + ElementMessageType_PAUSE ElementMessageType = 4 + ElementMessageType_CHECK 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 ) // Enum value maps for ElementMessageType. @@ -46,29 +46,29 @@ var ( 2: "CHAT_MESSAGE", 3: "PLAY", 4: "PAUSE", - 5: "CHECK_SEEK", + 5: "CHECK", 6: "TOO_FAST", 7: "TOO_SLOW", 8: "CHANGE_RATE", 9: "CHANGE_SEEK", - 10: "CHANGE_CURRENT", - 11: "CHANGE_MOVIES", - 12: "CHANGE_PEOPLE", + 10: "CURRENT_CHANGED", + 11: "MOVIES_CHANGED", + 12: "PEOPLE_CHANGED", } ElementMessageType_value = map[string]int32{ - "UNKNOWN": 0, - "ERROR": 1, - "CHAT_MESSAGE": 2, - "PLAY": 3, - "PAUSE": 4, - "CHECK_SEEK": 5, - "TOO_FAST": 6, - "TOO_SLOW": 7, - "CHANGE_RATE": 8, - "CHANGE_SEEK": 9, - "CHANGE_CURRENT": 10, - "CHANGE_MOVIES": 11, - "CHANGE_PEOPLE": 12, + "UNKNOWN": 0, + "ERROR": 1, + "CHAT_MESSAGE": 2, + "PLAY": 3, + "PAUSE": 4, + "CHECK": 5, + "TOO_FAST": 6, + "TOO_SLOW": 7, + "CHANGE_RATE": 8, + "CHANGE_SEEK": 9, + "CURRENT_CHANGED": 10, + "MOVIES_CHANGED": 11, + "PEOPLE_CHANGED": 12, } ) @@ -99,18 +99,17 @@ func (ElementMessageType) EnumDescriptor() ([]byte, []int) { return file_proto_message_message_proto_rawDescGZIP(), []int{0} } -type Status struct { +type ChatResp struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Seek float64 `protobuf:"fixed64,1,opt,name=seek,proto3" json:"seek,omitempty"` - Rate float64 `protobuf:"fixed64,2,opt,name=rate,proto3" json:"rate,omitempty"` - Playing bool `protobuf:"varint,3,opt,name=playing,proto3" json:"playing,omitempty"` + 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 *Status) Reset() { - *x = Status{} +func (x *ChatResp) Reset() { + *x = ChatResp{} if protoimpl.UnsafeEnabled { mi := &file_proto_message_message_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -118,13 +117,13 @@ func (x *Status) Reset() { } } -func (x *Status) String() string { +func (x *ChatResp) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Status) ProtoMessage() {} +func (*ChatResp) ProtoMessage() {} -func (x *Status) ProtoReflect() protoreflect.Message { +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)) @@ -136,30 +135,251 @@ func (x *Status) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Status.ProtoReflect.Descriptor instead. -func (*Status) Descriptor() ([]byte, []int) { +// Deprecated: Use ChatResp.ProtoReflect.Descriptor instead. +func (*ChatResp) Descriptor() ([]byte, []int) { return file_proto_message_message_proto_rawDescGZIP(), []int{0} } -func (x *Status) GetSeek() float64 { +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"` +} + +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) + } +} + +func (x *Sender) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Sender) ProtoMessage() {} + +func (x *Sender) ProtoReflect() protoreflect.Message { + mi := &file_proto_message_message_proto_msgTypes[1] + 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 Sender.ProtoReflect.Descriptor instead. +func (*Sender) Descriptor() ([]byte, []int) { + return file_proto_message_message_proto_rawDescGZIP(), []int{1} +} + +func (x *Sender) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *Sender) GetUserid() string { + if x != nil { + return x.Userid + } + return "" +} + +type MovieStatus 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"` +} + +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 *MovieStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MovieStatus) ProtoMessage() {} + +func (x *MovieStatus) ProtoReflect() protoreflect.Message { + mi := &file_proto_message_message_proto_msgTypes[2] + 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 MovieStatus.ProtoReflect.Descriptor instead. +func (*MovieStatus) Descriptor() ([]byte, []int) { + return file_proto_message_message_proto_rawDescGZIP(), []int{2} +} + +func (x *MovieStatus) GetPlaying() bool { + if x != nil { + return x.Playing + } + return false +} + +func (x *MovieStatus) GetSeek() float64 { if x != nil { return x.Seek } return 0 } -func (x *Status) GetRate() float64 { +func (x *MovieStatus) GetRate() float64 { if x != nil { return x.Rate } return 0 } -func (x *Status) GetPlaying() bool { +type MovieStatusChanged 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) + } +} + +func (x *MovieStatusChanged) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MovieStatusChanged) ProtoMessage() {} + +func (x *MovieStatusChanged) ProtoReflect() protoreflect.Message { + mi := &file_proto_message_message_proto_msgTypes[3] + 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 MovieStatusChanged.ProtoReflect.Descriptor instead. +func (*MovieStatusChanged) Descriptor() ([]byte, []int) { + return file_proto_message_message_proto_rawDescGZIP(), []int{3} +} + +func (x *MovieStatusChanged) GetSender() *Sender { if x != nil { - return x.Playing + return x.Sender } - return false + return nil +} + +func (x *MovieStatusChanged) GetStatus() *MovieStatus { + if x != nil { + return x.Status + } + return nil +} + +type CheckReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status *MovieStatus `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` + ExpireId uint64 `protobuf:"varint,2,opt,name=expireId,proto3" json:"expireId,omitempty"` +} + +func (x *CheckReq) Reset() { + *x = CheckReq{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_message_message_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CheckReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CheckReq) ProtoMessage() {} + +func (x *CheckReq) 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 CheckReq.ProtoReflect.Descriptor instead. +func (*CheckReq) Descriptor() ([]byte, []int) { + return file_proto_message_message_proto_rawDescGZIP(), []int{4} +} + +func (x *CheckReq) GetStatus() *MovieStatus { + if x != nil { + return x.Status + } + return nil +} + +func (x *CheckReq) GetExpireId() uint64 { + if x != nil { + return x.ExpireId + } + return 0 } type ElementMessage struct { @@ -167,19 +387,24 @@ type ElementMessage struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Type ElementMessageType `protobuf:"varint,1,opt,name=type,proto3,enum=proto.ElementMessageType" json:"type,omitempty"` - Sender string `protobuf:"bytes,2,opt,name=sender,proto3" json:"sender,omitempty"` - Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,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"` - PeopleNum int64 `protobuf:"varint,6,opt,name=peopleNum,proto3" json:"peopleNum,omitempty"` - Time int64 `protobuf:"varint,7,opt,name=time,proto3" json:"time,omitempty"` + 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"` + CheckReq *CheckReq `protobuf:"bytes,9,opt,name=checkReq,proto3" json:"checkReq,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[1] + mi := &file_proto_message_message_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -192,7 +417,7 @@ func (x *ElementMessage) String() string { func (*ElementMessage) ProtoMessage() {} func (x *ElementMessage) ProtoReflect() protoreflect.Message { - mi := &file_proto_message_message_proto_msgTypes[1] + mi := &file_proto_message_message_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -205,7 +430,7 @@ func (x *ElementMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use ElementMessage.ProtoReflect.Descriptor instead. func (*ElementMessage) Descriptor() ([]byte, []int) { - return file_proto_message_message_proto_rawDescGZIP(), []int{1} + return file_proto_message_message_proto_rawDescGZIP(), []int{5} } func (x *ElementMessage) GetType() ElementMessageType { @@ -215,86 +440,164 @@ func (x *ElementMessage) GetType() ElementMessageType { return ElementMessageType_UNKNOWN } -func (x *ElementMessage) GetSender() string { +func (x *ElementMessage) GetTime() int64 { if x != nil { - return x.Sender + return x.Time + } + return 0 +} + +func (x *ElementMessage) GetError() string { + if x != nil { + return x.Error } return "" } -func (x *ElementMessage) GetMessage() string { +func (x *ElementMessage) GetChatReq() string { if x != nil { - return x.Message + return x.ChatReq } return "" } -func (x *ElementMessage) GetRate() float64 { +func (x *ElementMessage) GetChatResp() *ChatResp { if x != nil { - return x.Rate + return x.ChatResp } - return 0 + return nil } -func (x *ElementMessage) GetSeek() float64 { +func (x *ElementMessage) GetChangeMovieStatusReq() *MovieStatus { if x != nil { - return x.Seek + return x.ChangeMovieStatusReq } - return 0 + return nil } -func (x *ElementMessage) GetPeopleNum() int64 { +func (x *ElementMessage) GetMovieStatusChanged() *MovieStatusChanged { if x != nil { - return x.PeopleNum + return x.MovieStatusChanged + } + return nil +} + +func (x *ElementMessage) GetChangeSeekReq() float64 { + if x != nil { + return x.ChangeSeekReq } return 0 } -func (x *ElementMessage) GetTime() int64 { +func (x *ElementMessage) GetCheckReq() *CheckReq { if x != nil { - return x.Time + return x.CheckReq + } + return nil +} + +func (x *ElementMessage) GetPeopleChanged() int64 { + if x != nil { + return x.PeopleChanged } return 0 } +func (x *ElementMessage) GetMoviesChanged() *Sender { + if x != nil { + return x.MoviesChanged + } + return nil +} + +func (x *ElementMessage) GetCurrentChanged() *Sender { + if x != nil { + return x.CurrentChanged + } + return nil +} + 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, 0x4a, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, - 0x0a, 0x04, 0x73, 0x65, 0x65, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x73, 0x65, - 0x65, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, - 0x52, 0x04, 0x72, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x69, 0x6e, - 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x69, 0x6e, 0x67, - 0x22, 0xcb, 0x01, 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, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x01, 0x52, 0x04, 0x72, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x65, 0x6b, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x73, 0x65, 0x65, 0x6b, 0x12, 0x1c, 0x0a, 0x09, - 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x4e, 0x75, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x09, 0x70, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x4e, 0x75, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x2a, 0xdb, - 0x01, 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, 0x0e, 0x0a, 0x0a, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x53, 0x45, - 0x45, 0x4b, 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, 0x12, 0x0a, 0x0e, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x43, 0x55, 0x52, - 0x52, 0x45, 0x4e, 0x54, 0x10, 0x0a, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, - 0x5f, 0x4d, 0x4f, 0x56, 0x49, 0x45, 0x53, 0x10, 0x0b, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x48, 0x41, - 0x4e, 0x47, 0x45, 0x5f, 0x50, 0x45, 0x4f, 0x50, 0x4c, 0x45, 0x10, 0x0c, 0x42, 0x06, 0x5a, 0x04, - 0x2e, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 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, 0x52, 0x0a, 0x08, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x52, 0x65, 0x71, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x01, 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, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x49, 0x64, 0x22, 0xa8, 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, 0x2b, 0x0a, 0x08, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x52, 0x65, 0x71, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x52, 0x08, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 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, 0xd9, 0x01, 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, 0x09, + 0x0a, 0x05, 0x43, 0x48, 0x45, 0x43, 0x4b, 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, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -310,19 +613,33 @@ 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, 2) +var file_proto_message_message_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_proto_message_message_proto_goTypes = []interface{}{ - (ElementMessageType)(0), // 0: proto.ElementMessageType - (*Status)(nil), // 1: proto.Status - (*ElementMessage)(nil), // 2: proto.ElementMessage + (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 + (*CheckReq)(nil), // 5: proto.CheckReq + (*ElementMessage)(nil), // 6: proto.ElementMessage } var file_proto_message_message_proto_depIdxs = []int32{ - 0, // 0: proto.ElementMessage.type:type_name -> proto.ElementMessageType - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 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 + 3, // 3: proto.CheckReq.status:type_name -> proto.MovieStatus + 0, // 4: proto.ElementMessage.type:type_name -> proto.ElementMessageType + 1, // 5: proto.ElementMessage.chatResp:type_name -> proto.ChatResp + 3, // 6: proto.ElementMessage.changeMovieStatusReq:type_name -> proto.MovieStatus + 4, // 7: proto.ElementMessage.movieStatusChanged:type_name -> proto.MovieStatusChanged + 5, // 8: proto.ElementMessage.checkReq:type_name -> proto.CheckReq + 2, // 9: proto.ElementMessage.moviesChanged:type_name -> proto.Sender + 2, // 10: proto.ElementMessage.currentChanged:type_name -> proto.Sender + 11, // [11:11] is the sub-list for method output_type + 11, // [11:11] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name } func init() { file_proto_message_message_proto_init() } @@ -332,7 +649,7 @@ func file_proto_message_message_proto_init() { } if !protoimpl.UnsafeEnabled { file_proto_message_message_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Status); i { + switch v := v.(*ChatResp); i { case 0: return &v.state case 1: @@ -344,6 +661,54 @@ func file_proto_message_message_proto_init() { } } 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.(*CheckReq); 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[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ElementMessage); i { case 0: return &v.state @@ -362,7 +727,7 @@ func file_proto_message_message_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_message_message_proto_rawDesc, NumEnums: 1, - NumMessages: 2, + NumMessages: 6, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/message/message.proto b/proto/message/message.proto index b945631..becdc9b 100644 --- a/proto/message/message.proto +++ b/proto/message/message.proto @@ -9,28 +9,53 @@ enum ElementMessageType { CHAT_MESSAGE = 2; PLAY = 3; PAUSE = 4; - CHECK_SEEK = 5; + CHECK = 5; TOO_FAST = 6; TOO_SLOW = 7; CHANGE_RATE = 8; CHANGE_SEEK = 9; - CHANGE_CURRENT = 10; - CHANGE_MOVIES = 11; - CHANGE_PEOPLE = 12; + CURRENT_CHANGED = 10; + MOVIES_CHANGED = 11; + PEOPLE_CHANGED = 12; } -message Status { - double seek = 1; - double rate = 2; - bool playing = 3; +message ChatResp { + Sender sender = 1; + string message = 2; +} + +message Sender { + string username = 1; + string userid = 2; +} + +message MovieStatus { + bool playing = 1; + double seek = 2; + double rate = 3; +} + +message MovieStatusChanged { + Sender sender = 1; + MovieStatus status = 2; +} + +message CheckReq { + MovieStatus status = 1; + uint64 expireId = 2; } message ElementMessage { ElementMessageType type = 1; - string sender = 2; - string message = 3; - double rate = 4; - double seek = 5; - int64 peopleNum = 6; - int64 time = 7; + int64 time = 2; + string error = 3; + string chatReq = 4; + ChatResp chatResp = 5; + MovieStatus changeMovieStatusReq = 6; + MovieStatusChanged movieStatusChanged = 7; + double changeSeekReq = 8; + CheckReq checkReq = 9; + int64 peopleChanged = 11; + Sender moviesChanged = 12; + Sender currentChanged = 13; } \ No newline at end of file diff --git a/proto/provider/plugin.pb.go b/proto/provider/plugin.pb.go index 02717a2..a3b0964 100644 --- a/proto/provider/plugin.pb.go +++ b/proto/provider/plugin.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 -// protoc v4.25.1 +// protoc-gen-go v1.32.0 +// protoc v4.25.2 // source: proto/provider/plugin.proto package providerpb diff --git a/proto/provider/plugin_grpc.pb.go b/proto/provider/plugin_grpc.pb.go index 8b7736b..58fc47f 100644 --- a/proto/provider/plugin_grpc.pb.go +++ b/proto/provider/plugin_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.3.0 -// - protoc v4.25.1 +// - protoc v4.25.2 // source: proto/provider/plugin.proto package providerpb diff --git a/server/handlers/movie.go b/server/handlers/movie.go index 1dfdd79..d7400ec 100644 --- a/server/handlers/movie.go +++ b/server/handlers/movie.go @@ -49,8 +49,7 @@ func MovieList(ctx *gin.Context) { return } - current := room.Current() - err = genCurrent(ctx, user, room, current) + currentResp, err := genCurrentResp(ctx, user, room) if err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err)) return @@ -71,27 +70,40 @@ func MovieList(ctx *gin.Context) { } } - current.UpdateSeek() - ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{ - "current": genCurrentResp(current), + "current": currentResp, "total": room.GetMoviesCount(), "movies": mresp, })) } -func genCurrent(ctx context.Context, user *op.User, room *op.Room, current *op.Current) error { - if current.Movie.Base.VendorInfo.Vendor != "" { - return parse2VendorMovie(ctx, user, room, ¤t.Movie) +func genCurrentResp(ctx context.Context, user *op.User, room *op.Room) (*model.CurrentMovieResp, error) { + return genCurrentRespWithCurrent(ctx, user, room, room.Current()) +} + +func genCurrentRespWithCurrent(ctx context.Context, user *op.User, room *op.Room, current *op.Current) (*model.CurrentMovieResp, error) { + if current.Movie.ID == "" { + return &model.CurrentMovieResp{}, nil } - if current.Movie.Base.RtmpSource || current.Movie.Base.Live && current.Movie.Base.Proxy { + opMovie, err := room.GetMovieByID(current.Movie.ID) + if err != nil { + return nil, err + } + var movie *dbModel.Movie = &opMovie.Movie + if current.Movie.Base.VendorInfo.Vendor != "" { + vendorMovie, err := genVendorMovie(ctx, user, opMovie) + if err != nil { + return nil, err + } + movie = vendorMovie + } else if current.Movie.Base.RtmpSource || current.Movie.Base.Live && current.Movie.Base.Proxy { switch current.Movie.Base.Type { case "m3u8": current.Movie.Base.Url = fmt.Sprintf("/api/movie/live/hls/list/%s.m3u8", current.Movie.ID) case "flv": current.Movie.Base.Url = fmt.Sprintf("/api/movie/live/flv/%s.flv", current.Movie.ID) default: - return errors.New("not support live movie type") + return nil, errors.New("not support live movie type") } current.Movie.Base.Headers = nil } else if current.Movie.Base.Proxy { @@ -101,37 +113,32 @@ func genCurrent(ctx context.Context, user *op.User, room *op.Room, current *op.C if current.Movie.Base.Type == "" && current.Movie.Base.Url != "" { current.Movie.Base.Type = utils.GetUrlExtension(current.Movie.Base.Url) } - return nil -} - -func genCurrentResp(current *op.Current) *model.CurrentMovieResp { - c := &model.CurrentMovieResp{ + current.UpdateSeek() + resp := &model.CurrentMovieResp{ Status: current.Status, Movie: model.MoviesResp{ - Id: current.Movie.ID, - CreatedAt: current.Movie.CreatedAt.UnixMilli(), - Base: current.Movie.Base, - Creator: op.GetUserName(current.Movie.CreatorID), - CreatorId: current.Movie.CreatorID, + Id: movie.ID, + CreatedAt: movie.CreatedAt.UnixMilli(), + Base: movie.Base, + Creator: op.GetUserName(movie.CreatorID), + CreatorId: movie.CreatorID, }, + ExpireId: opMovie.ExpireId(), } - return c + return resp, nil } func CurrentMovie(ctx *gin.Context) { room := ctx.MustGet("room").(*op.RoomEntry).Value() user := ctx.MustGet("user").(*op.UserEntry).Value() - current := room.Current() - err := genCurrent(ctx, user, room, current) + currentResp, err := genCurrentResp(ctx, user, room) if err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err)) return } - current.UpdateSeek() - - ctx.JSON(http.StatusOK, model.NewApiDataResp(genCurrentResp(current))) + ctx.JSON(http.StatusOK, model.NewApiDataResp(currentResp)) } func Movies(ctx *gin.Context) { @@ -186,9 +193,12 @@ func PushMovie(ctx *gin.Context) { return } - if err := room.Broadcast(&op.ElementMessage{ - Type: pb.ElementMessageType_CHANGE_MOVIES, - Sender: user.Username, + if err := room.Broadcast(&pb.ElementMessage{ + Type: pb.ElementMessageType_MOVIES_CHANGED, + MoviesChanged: &pb.Sender{ + Username: user.Username, + Userid: user.ID, + }, }); err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err)) return @@ -224,9 +234,12 @@ func PushMovies(ctx *gin.Context) { return } - if err := room.Broadcast(&op.ElementMessage{ - Type: pb.ElementMessageType_CHANGE_MOVIES, - Sender: user.Username, + if err := room.Broadcast(&pb.ElementMessage{ + Type: pb.ElementMessageType_MOVIES_CHANGED, + MoviesChanged: &pb.Sender{ + Username: user.Username, + Userid: user.ID, + }, }); err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err)) return @@ -302,9 +315,12 @@ func EditMovie(ctx *gin.Context) { return } - if err := room.Broadcast(&op.ElementMessage{ - Type: pb.ElementMessageType_CHANGE_MOVIES, - Sender: user.Username, + if err := room.Broadcast(&pb.ElementMessage{ + Type: pb.ElementMessageType_MOVIES_CHANGED, + MoviesChanged: &pb.Sender{ + Username: user.Username, + Userid: user.ID, + }, }); err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err)) return @@ -333,9 +349,12 @@ func DelMovie(ctx *gin.Context) { return } - if err := room.Broadcast(&op.ElementMessage{ - Type: pb.ElementMessageType_CHANGE_MOVIES, - Sender: user.Username, + if err := room.Broadcast(&pb.ElementMessage{ + Type: pb.ElementMessageType_MOVIES_CHANGED, + MoviesChanged: &pb.Sender{ + Username: user.Username, + Userid: user.ID, + }, }); err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err)) return @@ -357,9 +376,12 @@ func ClearMovies(ctx *gin.Context) { return } - if err := room.Broadcast(&op.ElementMessage{ - Type: pb.ElementMessageType_CHANGE_MOVIES, - Sender: user.Username, + if err := room.Broadcast(&pb.ElementMessage{ + Type: pb.ElementMessageType_MOVIES_CHANGED, + MoviesChanged: &pb.Sender{ + Username: user.Username, + Userid: user.ID, + }, }); err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err)) return @@ -383,9 +405,12 @@ func SwapMovie(ctx *gin.Context) { return } - if err := room.Broadcast(&op.ElementMessage{ - Type: pb.ElementMessageType_CHANGE_MOVIES, - Sender: user.Username, + if err := room.Broadcast(&pb.ElementMessage{ + Type: pb.ElementMessageType_MOVIES_CHANGED, + MoviesChanged: &pb.Sender{ + Username: user.Username, + Userid: user.ID, + }, }); err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err)) return @@ -418,9 +443,12 @@ func ChangeCurrentMovie(ctx *gin.Context) { ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) } - if err := room.Broadcast(&op.ElementMessage{ - Type: pb.ElementMessageType_CHANGE_CURRENT, - Sender: user.Username, + if err := room.Broadcast(&pb.ElementMessage{ + Type: pb.ElementMessageType_CURRENT_CHANGED, + CurrentChanged: &pb.Sender{ + Username: user.Username, + Userid: user.ID, + }, }); err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err)) return @@ -963,28 +991,26 @@ func proxyVendorMovie(ctx *gin.Context, movie *op.Movie) { } // user is the api requester -func parse2VendorMovie(ctx context.Context, user *op.User, room *op.Room, movie *dbModel.Movie) (err error) { +func genVendorMovie(ctx context.Context, user *op.User, opMovie *op.Movie) (*dbModel.Movie, error) { + movie := opMovie.Movie + var err error switch movie.Base.VendorInfo.Vendor { case dbModel.VendorBilibili: - opM, err := room.GetMovieByID(movie.ID) - if err != nil { - return err - } - bmc := opM.BilibiliCache() + bmc := opMovie.BilibiliCache() if !movie.Base.Proxy { var s string if movie.Base.VendorInfo.Bilibili.Shared { var u *op.UserEntry u, err = op.LoadOrInitUserByID(movie.CreatorID) if err != nil { - return err + return nil, err } - s, err = opM.BilibiliCache().NoSharedMovie.LoadOrStore(ctx, movie.CreatorID, u.Value().BilibiliCache()) + s, err = opMovie.BilibiliCache().NoSharedMovie.LoadOrStore(ctx, movie.CreatorID, u.Value().BilibiliCache()) } else { - s, err = opM.BilibiliCache().NoSharedMovie.LoadOrStore(ctx, user.ID, user.BilibiliCache()) + s, err = opMovie.BilibiliCache().NoSharedMovie.LoadOrStore(ctx, user.ID, user.BilibiliCache()) } if err != nil { - return err + return nil, err } movie.Base.Url = s @@ -994,7 +1020,7 @@ func parse2VendorMovie(ctx context.Context, user *op.User, room *op.Room, movie } srt, err := bmc.Subtitle.Get(ctx, user.BilibiliCache()) if err != nil { - return err + return nil, err } for k := range srt { if movie.Base.Subtitles == nil { @@ -1005,26 +1031,22 @@ func parse2VendorMovie(ctx context.Context, user *op.User, room *op.Room, movie Type: "srt", } } - return nil + return &movie, nil case dbModel.VendorAlist: creator, err := op.LoadOrInitUserByID(movie.CreatorID) if err != nil { - return err + return nil, err } - opM, err := room.GetMovieByID(movie.ID) + data, err := opMovie.AlistCache().Get(ctx, creator.Value().AlistCache()) if err != nil { - return err - } - data, err := opM.AlistCache().Get(ctx, creator.Value().AlistCache()) - if err != nil { - return err + return nil, err } if len(data.AliM3U8ListFile) != 0 { rawPath, err := url.JoinPath("/api/movie/proxy", movie.RoomID, movie.ID) if err != nil { - return err + return nil, err } u := url.URL{ Path: rawPath, @@ -1046,7 +1068,7 @@ func parse2VendorMovie(ctx context.Context, user *op.User, room *op.Room, movie } else { rawPath, err := url.JoinPath("/api/movie/proxy", movie.RoomID, movie.ID) if err != nil { - return err + return nil, err } u := url.URL{ Path: rawPath, @@ -1055,20 +1077,16 @@ func parse2VendorMovie(ctx context.Context, user *op.User, room *op.Room, movie movie.Base.Type = utils.GetUrlExtension(data.URL) } movie.Base.VendorInfo.Alist.Password = "" - return nil + return &movie, nil case dbModel.VendorEmby: u, err := op.LoadOrInitUserByID(movie.CreatorID) if err != nil { - return err + return nil, err } - opM, err := room.GetMovieByID(movie.ID) + data, err := opMovie.EmbyCache().Get(ctx, u.Value().EmbyCache()) if err != nil { - return err - } - data, err := opM.EmbyCache().Get(ctx, u.Value().EmbyCache()) - if err != nil { - return err + return nil, err } if !movie.Base.Proxy { @@ -1078,7 +1096,7 @@ func parse2VendorMovie(ctx context.Context, user *op.User, room *op.Room, movie continue } if movie.Base.Url == "" { - return errors.New("no source") + return nil, errors.New("no source") } } movie.Base.Url = es.URLs[0].URL @@ -1103,13 +1121,13 @@ func parse2VendorMovie(ctx context.Context, user *op.User, room *op.Room, movie continue } if movie.Base.Url == "" { - return errors.New("no source") + return nil, errors.New("no source") } } rawPath, err := url.JoinPath("/api/movie/proxy", movie.RoomID, movie.ID) if err != nil { - return err + return nil, err } rawQuery := url.Values{} rawQuery.Set("source", strconv.Itoa(si)) @@ -1144,9 +1162,9 @@ func parse2VendorMovie(ctx context.Context, user *op.User, room *op.Room, movie } } - return nil + return &movie, nil default: - return fmt.Errorf("vendor not implement gen movie url") + return nil, fmt.Errorf("vendor not implement gen movie url") } } diff --git a/server/handlers/websocket.go b/server/handlers/websocket.go index d826d5d..dda9881 100644 --- a/server/handlers/websocket.go +++ b/server/handlers/websocket.go @@ -43,9 +43,9 @@ func NewWSMessageHandler(uE *op.UserEntry, rE *op.RoomEntry) func(c *websocket.C return err2 } defer wc.Close() - em := op.ElementMessage{ - Type: pb.ElementMessageType_ERROR, - Message: err.Error(), + em := pb.ElementMessage{ + Type: pb.ElementMessageType_ERROR, + Error: err.Error(), } return em.Encode(wc) } @@ -97,9 +97,9 @@ func handleReaderMessage(c *op.Client) error { var data []byte if data, err = io.ReadAll(rd); err != nil { log.Errorf("ws: room %s user %s read message error: %v", c.Room().Name, c.User().Username, err) - if err := c.Send(&op.ElementMessage{ - Type: pb.ElementMessageType_ERROR, - Message: err.Error(), + if err := c.Send(&pb.ElementMessage{ + Type: pb.ElementMessageType_ERROR, + Error: err.Error(), }); err != nil { log.Errorf("ws: room %s user %s send error message error: %v", c.Room().Name, c.User().Username, err) return err @@ -109,9 +109,9 @@ func handleReaderMessage(c *op.Client) error { var msg pb.ElementMessage if err := proto.Unmarshal(data, &msg); err != nil { log.Errorf("ws: room %s user %s decode message error: %v", c.Room().Name, c.User().Username, err) - if err := c.Send(&op.ElementMessage{ - Type: pb.ElementMessageType_ERROR, - Message: err.Error(), + if err := c.Send(&pb.ElementMessage{ + Type: pb.ElementMessageType_ERROR, + Error: err.Error(), }); err != nil { log.Errorf("ws: room %s user %s send error message error: %v", c.Room().Name, c.User().Username, err) return err @@ -132,15 +132,9 @@ func handleReaderMessage(c *op.Client) error { } } +const MaxChatMessageLength = 4096 + func handleElementMsg(cli *op.Client, msg *pb.ElementMessage) error { - var send = func(em *pb.ElementMessage) error { - em.Sender = cli.User().Username - return cli.Send((*op.ElementMessage)(em)) - } - var broadcast = func(em *pb.ElementMessage, bc ...op.BroadcastConf) error { - em.Sender = cli.User().Username - return cli.Broadcast((*op.ElementMessage)(em), bc...) - } var timeDiff float64 if msg.Time != 0 { timeDiff = time.Since(time.UnixMilli(msg.Time)).Seconds() @@ -154,64 +148,84 @@ func handleElementMsg(cli *op.Client, msg *pb.ElementMessage) error { } switch msg.Type { case pb.ElementMessageType_CHAT_MESSAGE: - if len(msg.Message) > 4096 { - send(&pb.ElementMessage{ - Type: pb.ElementMessageType_ERROR, - Message: "message too long", + message := msg.GetChatReq() + if len(message) > MaxChatMessageLength { + cli.Send(&pb.ElementMessage{ + Type: pb.ElementMessageType_ERROR, + Error: "message too long", }) return nil } - broadcast(&pb.ElementMessage{ - Type: pb.ElementMessageType_CHAT_MESSAGE, - Message: msg.Message, + cli.Broadcast(&pb.ElementMessage{ + Type: pb.ElementMessageType_CHAT_MESSAGE, + ChatResp: &pb.ChatResp{ + Sender: &pb.Sender{ + Username: cli.User().Username, + Userid: cli.User().ID, + }, + Message: message, + }, }) - case pb.ElementMessageType_PLAY: - status := cli.Room().SetStatus(true, msg.Seek, msg.Rate, timeDiff) - broadcast(&pb.ElementMessage{ - Type: pb.ElementMessageType_PLAY, - Seek: status.Seek, - Rate: status.Rate, - }, op.WithIgnoreClient(cli)) - case pb.ElementMessageType_PAUSE: - status := cli.Room().SetStatus(false, msg.Seek, msg.Rate, timeDiff) - broadcast(&pb.ElementMessage{ - Type: pb.ElementMessageType_PAUSE, - Seek: status.Seek, - Rate: status.Rate, - }, op.WithIgnoreClient(cli)) - case pb.ElementMessageType_CHANGE_RATE: - status := cli.Room().SetSeekRate(msg.Seek, msg.Rate, timeDiff) - broadcast(&pb.ElementMessage{ - Type: pb.ElementMessageType_CHANGE_RATE, - Seek: status.Seek, - Rate: status.Rate, + case pb.ElementMessageType_PLAY, + pb.ElementMessageType_PAUSE, + pb.ElementMessageType_CHANGE_RATE, + pb.ElementMessageType_CHANGE_SEEK: + status := cli.Room().SetStatus(msg.ChangeMovieStatusReq.Playing, msg.ChangeMovieStatusReq.Seek, msg.ChangeMovieStatusReq.Rate, timeDiff) + 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_CHANGE_SEEK: - status := cli.Room().SetSeekRate(msg.Seek, msg.Rate, timeDiff) - broadcast(&pb.ElementMessage{ - Type: pb.ElementMessageType_CHANGE_SEEK, - Seek: status.Seek, - Rate: status.Rate, - }, op.WithIgnoreClient(cli)) - case pb.ElementMessageType_CHECK_SEEK: - status := cli.Room().Current().Status - if status.Seek+maxInterval < msg.Seek+timeDiff { - send(&pb.ElementMessage{ + case pb.ElementMessageType_CHECK: + current := cli.Room().Current() + if msg.CheckReq.ExpireId != 0 { + currentMovie, err := cli.Room().GetMovieByID(current.Movie.ID) + if err != nil { + _ = cli.Send(&pb.ElementMessage{ + Type: pb.ElementMessageType_ERROR, + Error: err.Error(), + }) + break + } + if currentMovie.CheckExpired(msg.CheckReq.ExpireId) { + _ = cli.Send(&pb.ElementMessage{ + Type: pb.ElementMessageType_CURRENT_CHANGED, + }) + break + } + } + status := current.Status + cliStatus := msg.CheckReq.Status + if status.Seek+maxInterval < cliStatus.Seek+timeDiff { + cli.Send(&pb.ElementMessage{ Type: pb.ElementMessageType_TOO_FAST, - Seek: status.Seek, - Rate: status.Rate, + MovieStatusChanged: &pb.MovieStatusChanged{ + Status: &pb.MovieStatus{ + Playing: status.Playing, + Seek: status.Seek, + Rate: status.Rate, + }, + }, }) - } else if status.Seek-maxInterval > msg.Seek+timeDiff { - send(&pb.ElementMessage{ + } else if status.Seek-maxInterval > cliStatus.Seek+timeDiff { + cli.Send(&pb.ElementMessage{ Type: pb.ElementMessageType_TOO_SLOW, - Seek: status.Seek, - Rate: status.Rate, - }) - } else { - send(&pb.ElementMessage{ - Type: pb.ElementMessageType_CHECK_SEEK, - Seek: status.Seek, - Rate: status.Rate, + MovieStatusChanged: &pb.MovieStatusChanged{ + Status: &pb.MovieStatus{ + Playing: status.Playing, + Seek: status.Seek, + Rate: status.Rate, + }, + }, }) } } diff --git a/server/model/movie.go b/server/model/movie.go index e586938..31f47c0 100644 --- a/server/model/movie.go +++ b/server/model/movie.go @@ -154,6 +154,7 @@ type MoviesResp struct { } type CurrentMovieResp struct { - Status op.Status `json:"status"` - Movie MoviesResp `json:"movie"` + Status op.Status `json:"status"` + Movie MoviesResp `json:"movie"` + ExpireId uint64 `json:"expireId"` }