diff --git a/go.mod b/go.mod index 9636c88..0a45ce0 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/gin-gonic/gin v1.9.1 github.com/go-resty/resty/v2 v2.9.1 github.com/golang-jwt/jwt/v5 v5.0.0 + github.com/golang/protobuf v1.5.3 github.com/google/uuid v1.3.1 github.com/gorilla/websocket v1.5.0 github.com/json-iterator/go v1.1.12 @@ -20,11 +21,11 @@ require ( github.com/spf13/cobra v1.7.0 github.com/zijiren233/gencontainer v0.0.0-20230930135658-e410015e13cc github.com/zijiren233/go-colorable v0.0.0-20230930131441-997304c961cb - github.com/zijiren233/ksync v0.2.0 github.com/zijiren233/livelib v0.1.2-0.20231010145337-1651f7b4be26 github.com/zijiren233/stream v0.5.1 github.com/zijiren233/yaml-comment v0.2.0 golang.org/x/crypto v0.14.0 + google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -62,6 +63,5 @@ require ( golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/tools v0.14.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect ) diff --git a/go.sum b/go.sum index 3823648..cbbeea5 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,6 @@ github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8 github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= -github.com/bytedance/sonic v1.10.1 h1:7a1wuFXL1cMy7a3f7/VFcEtriuXQnUBhtoVfOZiaysc= -github.com/bytedance/sonic v1.10.1/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= github.com/bytedance/sonic v1.10.2 h1:GQebETVBxYB7JGWJtLBi07OVzWwt+8dWA00gEVW2ZFE= github.com/bytedance/sonic v1.10.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= github.com/caarlos0/env/v9 v9.0.0 h1:SI6JNsOA+y5gj9njpgybykATIylrRMklbs5ch6wO6pc= @@ -38,12 +36,8 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= -github.com/go-playground/validator/v10 v10.15.4 h1:zMXza4EpOdooxPel5xDqXEdXG5r+WggpvnAKMsalBjs= -github.com/go-playground/validator/v10 v10.15.4/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24= github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-resty/resty/v2 v2.8.0 h1:J29d0JFWwSWrDCysnOK/YjsPMLQTx0TvgJEHVGvf2L8= -github.com/go-resty/resty/v2 v2.8.0/go.mod h1:UCui0cMHekLrSntoMyofdSTaPpinlRHFtPpizuyDW2w= github.com/go-resty/resty/v2 v2.9.1 h1:PIgGx4VrHvag0juCJ4dDv3MiFRlDmP0vicBucwf+gLM= github.com/go-resty/resty/v2 v2.9.1/go.mod h1:4/GYJVjh9nhkhGR6AUNW3XhpDYNUr+Uvy9gV/VGZIy4= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= @@ -55,6 +49,7 @@ github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJ github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -97,8 +92,6 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM= github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk= -github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA= -github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= @@ -145,24 +138,10 @@ github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95 github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zijiren233/gencontainer v0.0.0-20230930061950-82324a07eacb h1:sOVY4BfQo/uzoACkFTvfCJd0mHhhPQjcwgKTICOW+Js= -github.com/zijiren233/gencontainer v0.0.0-20230930061950-82324a07eacb/go.mod h1:V5oL7PrZxgisuLCblFWd89Jg99O8vM1n58llcxZ2hDY= github.com/zijiren233/gencontainer v0.0.0-20230930135658-e410015e13cc h1:qEYdClJZG4GHT7pG+scIkN36u5/n1uj5bAPt8UeLkO4= github.com/zijiren233/gencontainer v0.0.0-20230930135658-e410015e13cc/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/ksync v0.2.0 h1:OyXVXbVQYFEVfWM13NApt4LMHbLQ3HTs4oYcLmqL6NE= -github.com/zijiren233/ksync v0.2.0/go.mod h1:YNvvoErcbtF86Xn18J8QJ14jKOXinxFVOzyp4hn8FKw= -github.com/zijiren233/livelib v0.0.0-20230930062256-1d07bbddcefb h1:t6zLooW4uVz2gKWmbZN4ljXKJpbiLnQF9j1kTMfV8OM= -github.com/zijiren233/livelib v0.0.0-20230930062256-1d07bbddcefb/go.mod h1:C4OwAodQXpMLYiioqH4ANjZJD4+sFRK0nPbXNoYZU5k= -github.com/zijiren233/livelib v0.0.0-20231005100909-7893feb306a9 h1:GRhW0AmqeUN0CbAzJQhQXQ5sz139/lMn6yuD+ZBVn/s= -github.com/zijiren233/livelib v0.0.0-20231005100909-7893feb306a9/go.mod h1:2wrAAqNIdMZjQrdbO7ERQfqK4VS5fzgUj2xXwrJ8/uo= -github.com/zijiren233/livelib v0.1.0 h1:QdNj39eaIB/g7bBhDFbwrDuGkoghHWEwZXgBVwQ5QtY= -github.com/zijiren233/livelib v0.1.0/go.mod h1:2wrAAqNIdMZjQrdbO7ERQfqK4VS5fzgUj2xXwrJ8/uo= -github.com/zijiren233/livelib v0.1.1 h1:PjGqQXgJw2sqWWBp5JEtwqnpNplWqX5BY3yo+5U9vOo= -github.com/zijiren233/livelib v0.1.1/go.mod h1:2wrAAqNIdMZjQrdbO7ERQfqK4VS5fzgUj2xXwrJ8/uo= -github.com/zijiren233/livelib v0.1.2-0.20231010021513-5130877d6f5e h1:x1KhyR/CIaZ2Yfb1mGwX0nUhRVOJnFPUFNN+AVqv7VA= -github.com/zijiren233/livelib v0.1.2-0.20231010021513-5130877d6f5e/go.mod h1:2wrAAqNIdMZjQrdbO7ERQfqK4VS5fzgUj2xXwrJ8/uo= github.com/zijiren233/livelib v0.1.2-0.20231010145337-1651f7b4be26 h1:h7cw3cPQX3VheviU0y0bUVV0CnQ8fJegJgZMBpb/tfw= github.com/zijiren233/livelib v0.1.2-0.20231010145337-1651f7b4be26/go.mod h1:2wrAAqNIdMZjQrdbO7ERQfqK4VS5fzgUj2xXwrJ8/uo= github.com/zijiren233/stream v0.5.1 h1:9SUwM/fpET6frtBRT5WZBHnan0Hyzkezk/P8N78cgZQ= @@ -178,18 +157,13 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -199,7 +173,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= @@ -219,7 +192,6 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -236,18 +208,18 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 h1:GZokNIeuVkl3aZHJchRrr13WCsols02MLUcz1U9is6M= golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= diff --git a/proto.sh b/proto.sh new file mode 100644 index 0000000..91f3f4e --- /dev/null +++ b/proto.sh @@ -0,0 +1,2 @@ +#!/bin/bash +protoc --go_out=./proto ./proto/*.proto diff --git a/proto/message.pb.go b/proto/message.pb.go new file mode 100644 index 0000000..d9e4216 --- /dev/null +++ b/proto/message.pb.go @@ -0,0 +1,632 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v4.24.4 +// source: proto/message.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +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 +) + +// Enum value maps for ElementMessageType. +var ( + ElementMessageType_name = map[int32]string{ + 0: "UNKNOWN", + 1: "ERROR", + 2: "CHAT_MESSAGE", + 3: "PLAY", + 4: "PAUSE", + 5: "CHECK_SEEK", + 6: "TOO_FAST", + 7: "TOO_SLOW", + 8: "CHANGE_RATE", + 9: "CHANGE_SEEK", + 10: "CHANGE_CURRENT", + 11: "CHANGE_MOVIES", + 12: "CHANGE_PEOPLE", + } + 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, + } +) + +func (x ElementMessageType) Enum() *ElementMessageType { + p := new(ElementMessageType) + *p = x + return p +} + +func (x ElementMessageType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ElementMessageType) Descriptor() protoreflect.EnumDescriptor { + return file_proto_message_proto_enumTypes[0].Descriptor() +} + +func (ElementMessageType) Type() protoreflect.EnumType { + return &file_proto_message_proto_enumTypes[0] +} + +func (x ElementMessageType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ElementMessageType.Descriptor instead. +func (ElementMessageType) EnumDescriptor() ([]byte, []int) { + return file_proto_message_proto_rawDescGZIP(), []int{0} +} + +type MovieInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Live bool `protobuf:"varint,4,opt,name=live,proto3" json:"live,omitempty"` + Proxy bool `protobuf:"varint,5,opt,name=proxy,proto3" json:"proxy,omitempty"` + RtmpSource bool `protobuf:"varint,6,opt,name=rtmp_source,json=rtmpSource,proto3" json:"rtmp_source,omitempty"` + Type string `protobuf:"bytes,7,opt,name=type,proto3" json:"type,omitempty"` + Headers map[string]string `protobuf:"bytes,8,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + PullKey string `protobuf:"bytes,9,opt,name=pull_key,json=pullKey,proto3" json:"pull_key,omitempty"` + CreatedAt int64 `protobuf:"varint,10,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + Creator string `protobuf:"bytes,11,opt,name=creator,proto3" json:"creator,omitempty"` +} + +func (x *MovieInfo) Reset() { + *x = MovieInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_message_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MovieInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MovieInfo) ProtoMessage() {} + +func (x *MovieInfo) ProtoReflect() protoreflect.Message { + mi := &file_proto_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 MovieInfo.ProtoReflect.Descriptor instead. +func (*MovieInfo) Descriptor() ([]byte, []int) { + return file_proto_message_proto_rawDescGZIP(), []int{0} +} + +func (x *MovieInfo) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *MovieInfo) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +func (x *MovieInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *MovieInfo) GetLive() bool { + if x != nil { + return x.Live + } + return false +} + +func (x *MovieInfo) GetProxy() bool { + if x != nil { + return x.Proxy + } + return false +} + +func (x *MovieInfo) GetRtmpSource() bool { + if x != nil { + return x.RtmpSource + } + return false +} + +func (x *MovieInfo) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *MovieInfo) GetHeaders() map[string]string { + if x != nil { + return x.Headers + } + return nil +} + +func (x *MovieInfo) GetPullKey() string { + if x != nil { + return x.PullKey + } + return "" +} + +func (x *MovieInfo) GetCreatedAt() int64 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +func (x *MovieInfo) GetCreator() string { + if x != nil { + return x.Creator + } + return "" +} + +type Status 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"` +} + +func (x *Status) Reset() { + *x = Status{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_message_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Status) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Status) ProtoMessage() {} + +func (x *Status) ProtoReflect() protoreflect.Message { + mi := &file_proto_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 Status.ProtoReflect.Descriptor instead. +func (*Status) Descriptor() ([]byte, []int) { + return file_proto_message_proto_rawDescGZIP(), []int{1} +} + +func (x *Status) GetSeek() float64 { + if x != nil { + return x.Seek + } + return 0 +} + +func (x *Status) GetRate() float64 { + if x != nil { + return x.Rate + } + return 0 +} + +func (x *Status) GetPlaying() bool { + if x != nil { + return x.Playing + } + return false +} + +type Current struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Movie *MovieInfo `protobuf:"bytes,1,opt,name=movie,proto3" json:"movie,omitempty"` + Status *Status `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` +} + +func (x *Current) Reset() { + *x = Current{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_message_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Current) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Current) ProtoMessage() {} + +func (x *Current) ProtoReflect() protoreflect.Message { + mi := &file_proto_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 Current.ProtoReflect.Descriptor instead. +func (*Current) Descriptor() ([]byte, []int) { + return file_proto_message_proto_rawDescGZIP(), []int{2} +} + +func (x *Current) GetMovie() *MovieInfo { + if x != nil { + return x.Movie + } + return nil +} + +func (x *Current) GetStatus() *Status { + 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"` + 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"` + Current *Current `protobuf:"bytes,6,opt,name=current,proto3,oneof" json:"current,omitempty"` + PeopleNum int64 `protobuf:"varint,7,opt,name=people_num,json=peopleNum,proto3" json:"people_num,omitempty"` + Time int64 `protobuf:"varint,8,opt,name=time,proto3" json:"time,omitempty"` +} + +func (x *ElementMessage) Reset() { + *x = ElementMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_message_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ElementMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ElementMessage) ProtoMessage() {} + +func (x *ElementMessage) ProtoReflect() protoreflect.Message { + mi := &file_proto_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 ElementMessage.ProtoReflect.Descriptor instead. +func (*ElementMessage) Descriptor() ([]byte, []int) { + return file_proto_message_proto_rawDescGZIP(), []int{3} +} + +func (x *ElementMessage) GetType() ElementMessageType { + if x != nil { + return x.Type + } + return ElementMessageType_UNKNOWN +} + +func (x *ElementMessage) GetSender() string { + if x != nil { + return x.Sender + } + return "" +} + +func (x *ElementMessage) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *ElementMessage) GetRate() float64 { + if x != nil { + return x.Rate + } + return 0 +} + +func (x *ElementMessage) GetSeek() float64 { + if x != nil { + return x.Seek + } + return 0 +} + +func (x *ElementMessage) GetCurrent() *Current { + if x != nil { + return x.Current + } + return nil +} + +func (x *ElementMessage) GetPeopleNum() int64 { + if x != nil { + return x.PeopleNum + } + return 0 +} + +func (x *ElementMessage) GetTime() int64 { + if x != nil { + return x.Time + } + return 0 +} + +var File_proto_message_proto protoreflect.FileDescriptor + +var file_proto_message_proto_rawDesc = []byte{ + 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe9, 0x02, 0x0a, + 0x09, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, + 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, + 0x6c, 0x69, 0x76, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x74, + 0x6d, 0x70, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0a, 0x72, 0x74, 0x6d, 0x70, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x37, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x49, 0x6e, + 0x66, 0x6f, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x75, 0x6c, 0x6c, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x75, 0x6c, 0x6c, + 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x41, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x1a, 0x3a, 0x0a, 0x0c, + 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 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, 0x58, 0x0a, 0x07, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, + 0x26, 0x0a, 0x05, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x05, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x87, + 0x02, 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, 0x2d, 0x0a, 0x07, 0x63, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x07, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x65, 0x6f, + 0x70, 0x6c, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x70, + 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x4e, 0x75, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x42, 0x0a, 0x0a, 0x08, + 0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 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, +} + +var ( + file_proto_message_proto_rawDescOnce sync.Once + file_proto_message_proto_rawDescData = file_proto_message_proto_rawDesc +) + +func file_proto_message_proto_rawDescGZIP() []byte { + file_proto_message_proto_rawDescOnce.Do(func() { + file_proto_message_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_message_proto_rawDescData) + }) + return file_proto_message_proto_rawDescData +} + +var file_proto_message_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_proto_message_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_proto_message_proto_goTypes = []interface{}{ + (ElementMessageType)(0), // 0: proto.ElementMessageType + (*MovieInfo)(nil), // 1: proto.MovieInfo + (*Status)(nil), // 2: proto.Status + (*Current)(nil), // 3: proto.Current + (*ElementMessage)(nil), // 4: proto.ElementMessage + nil, // 5: proto.MovieInfo.HeadersEntry +} +var file_proto_message_proto_depIdxs = []int32{ + 5, // 0: proto.MovieInfo.headers:type_name -> proto.MovieInfo.HeadersEntry + 1, // 1: proto.Current.movie:type_name -> proto.MovieInfo + 2, // 2: proto.Current.status:type_name -> proto.Status + 0, // 3: proto.ElementMessage.type:type_name -> proto.ElementMessageType + 3, // 4: proto.ElementMessage.current:type_name -> proto.Current + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_proto_message_proto_init() } +func file_proto_message_proto_init() { + if File_proto_message_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_proto_message_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MovieInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_message_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Status); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_message_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Current); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_message_proto_msgTypes[3].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_proto_msgTypes[3].OneofWrappers = []interface{}{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_message_proto_rawDesc, + NumEnums: 1, + NumMessages: 5, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_proto_message_proto_goTypes, + DependencyIndexes: file_proto_message_proto_depIdxs, + EnumInfos: file_proto_message_proto_enumTypes, + MessageInfos: file_proto_message_proto_msgTypes, + }.Build() + File_proto_message_proto = out.File + file_proto_message_proto_rawDesc = nil + file_proto_message_proto_goTypes = nil + file_proto_message_proto_depIdxs = nil +} diff --git a/proto/message.proto b/proto/message.proto new file mode 100644 index 0000000..a82da69 --- /dev/null +++ b/proto/message.proto @@ -0,0 +1,56 @@ +syntax = "proto3"; +option go_package = ".;pb"; + +package proto; + +enum ElementMessageType { + 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; +} + +message MovieInfo { + uint64 id = 1; + string url = 2; + string name = 3; + bool live = 4; + bool proxy = 5; + bool rtmp_source = 6; + string type = 7; + map headers = 8; + string pull_key = 9; + int64 created_at = 10; + string creator = 11; +} + +message Status { + double seek = 1; + double rate = 2; + bool playing = 3; +} + +message Current { + MovieInfo movie = 1; + Status status = 2; +} + +message ElementMessage { + ElementMessageType type = 1; + string sender = 2; + string message = 3; + double rate = 4; + double seek = 5; + optional Current current = 6; + int64 people_num = 7; + int64 time = 8; +} \ No newline at end of file diff --git a/room/client.go b/room/client.go index 0a2b5b5..08656bb 100644 --- a/room/client.go +++ b/room/client.go @@ -46,8 +46,8 @@ func (c *Client) Room() *Room { return c.user.room } -func (c *Client) Broadcast(msg Message, conf ...BroadcastConf) { - c.user.Broadcast(msg, conf...) +func (c *Client) Broadcast(msg Message, conf ...BroadcastConf) error { + return c.user.Broadcast(msg, conf...) } func (c *Client) Send(msg Message) error { diff --git a/room/current.go b/room/current.go index a13a598..fbaf60c 100644 --- a/room/current.go +++ b/room/current.go @@ -4,136 +4,165 @@ import ( "sync" "time" - json "github.com/json-iterator/go" + pb "github.com/synctv-org/synctv/proto" ) +type current struct { + current Current + lock sync.RWMutex +} + type Current struct { - movie MovieInfo - status Status - lock sync.RWMutex + Movie MovieInfo `json:"movie"` + Status Status `json:"status"` } -func newCurrent() *Current { - return &Current{ - movie: MovieInfo{}, - status: newStatus(), +func newCurrent() *current { + return ¤t{ + current: Current{ + Status: newStatus(), + }, } } type Status struct { - Seek float64 `json:"seek"` - Rate float64 `json:"rate"` - Playing bool `json:"playing"` - lastUpdateTime time.Time + Seek float64 `json:"seek"` + Rate float64 `json:"rate"` + Playing bool `json:"playing"` + lastUpdate time.Time } func newStatus() Status { return Status{ - Seek: 0, - Rate: 1.0, - lastUpdateTime: time.Now(), + Seek: 0, + Rate: 1.0, + lastUpdate: time.Now(), } } -func (c *Current) MarshalJSON() ([]byte, error) { +func (c *current) Current() Current { c.lock.RLock() defer c.lock.RUnlock() - c.updateSeek() - return json.Marshal(map[string]interface{}{ - "movie": c.movie, - "status": c.status, - }) + c.current.updateSeek() + return c.current } -func (c *Current) Movie() MovieInfo { +func (c *current) Movie() MovieInfo { c.lock.RLock() defer c.lock.RUnlock() - return c.movie + return c.current.Movie } -func (c *Current) SetMovie(movie MovieInfo) { +func (c *current) SetMovie(movie MovieInfo) { c.lock.Lock() defer c.lock.Unlock() - c.movie = movie - c.setSeek(0, 0) + c.current.Movie = movie + c.current.SetSeek(0, 0) } -func (c *Current) Status() Status { +func (c *current) Status() Status { c.lock.RLock() defer c.lock.RUnlock() - c.updateSeek() - return c.status + c.current.updateSeek() + return c.current.Status +} + +func (c *current) SetStatus(playing bool, seek, rate, timeDiff float64) Status { + c.lock.Lock() + defer c.lock.Unlock() + + return c.current.SetStatus(playing, seek, rate, timeDiff) +} + +func (c *current) SetSeekRate(seek, rate, timeDiff float64) Status { + c.lock.Lock() + defer c.lock.Unlock() + + return c.current.SetSeekRate(seek, rate, timeDiff) +} + +func (c *Current) Proto() *pb.Current { + return &pb.Current{ + Movie: &pb.MovieInfo{ + Id: c.Movie.Id, + Url: c.Movie.Url, + Name: c.Movie.Name, + Live: c.Movie.Live, + Proxy: c.Movie.Proxy, + RtmpSource: c.Movie.RtmpSource, + Type: c.Movie.Type, + Headers: c.Movie.Headers, + PullKey: c.Movie.PullKey, + CreatedAt: c.Movie.CreatedAt, + Creator: c.Movie.Creator, + }, + Status: &pb.Status{ + Seek: c.Status.Seek, + Rate: c.Status.Rate, + Playing: c.Status.Playing, + }, + } } func (c *Current) updateSeek() { - if c.movie.Live { - c.status.lastUpdateTime = time.Now() + if c.Movie.Live { + c.Status.lastUpdate = time.Now() return } - if c.status.Playing { - c.status.Seek += time.Since(c.status.lastUpdateTime).Seconds() * c.status.Rate + if c.Status.Playing { + c.Status.Seek += time.Since(c.Status.lastUpdate).Seconds() * c.Status.Rate } - c.status.lastUpdateTime = time.Now() + c.Status.lastUpdate = time.Now() } func (c *Current) setLiveStatus() Status { - c.status.Playing = true - c.status.Rate = 1.0 - c.status.Seek = 0 - c.status.lastUpdateTime = time.Now() - return c.status + c.Status.Playing = true + c.Status.Rate = 1.0 + c.Status.Seek = 0 + c.Status.lastUpdate = time.Now() + return c.Status } func (c *Current) SetStatus(playing bool, seek, rate, timeDiff float64) Status { - c.lock.Lock() - defer c.lock.Unlock() - if c.movie.Live { + if c.Movie.Live { return c.setLiveStatus() } - c.status.Playing = playing - c.status.Rate = rate + c.Status.Playing = playing + c.Status.Rate = rate if playing { - c.status.Seek = seek + (timeDiff * rate) + c.Status.Seek = seek + (timeDiff * rate) } else { - c.status.Seek = seek + c.Status.Seek = seek } - c.status.lastUpdateTime = time.Now() - return c.status + c.Status.lastUpdate = time.Now() + return c.Status } func (c *Current) SetSeekRate(seek, rate, timeDiff float64) Status { - c.lock.Lock() - defer c.lock.Unlock() - if c.movie.Live { + if c.Movie.Live { return c.setLiveStatus() } - if c.status.Playing { - c.status.Seek = seek + (timeDiff * rate) + if c.Status.Playing { + c.Status.Seek = seek + (timeDiff * rate) } else { - c.status.Seek = seek + c.Status.Seek = seek } - c.status.Rate = rate - c.status.lastUpdateTime = time.Now() - return c.status + c.Status.Rate = rate + c.Status.lastUpdate = time.Now() + return c.Status } func (c *Current) SetSeek(seek, timeDiff float64) Status { - c.lock.Lock() - defer c.lock.Unlock() - return c.setSeek(seek, timeDiff) -} - -func (c *Current) setSeek(seek, timeDiff float64) Status { - if c.movie.Live { + if c.Movie.Live { return c.setLiveStatus() } - if c.status.Playing { - c.status.Seek = seek + (timeDiff * c.status.Rate) + if c.Status.Playing { + c.Status.Seek = seek + (timeDiff * c.Status.Rate) } else { - c.status.Seek = seek + c.Status.Seek = seek } - c.status.lastUpdateTime = time.Now() - return c.status + c.Status.lastUpdate = time.Now() + return c.Status } diff --git a/room/message.go b/room/message.go index 28ab1bb..63c3991 100644 --- a/room/message.go +++ b/room/message.go @@ -1,12 +1,11 @@ package room import ( - "encoding/json" - "fmt" "io" "github.com/gorilla/websocket" - "gopkg.in/yaml.v3" + pb "github.com/synctv-org/synctv/proto" + "google.golang.org/protobuf/proto" ) type Message interface { @@ -15,72 +14,54 @@ type Message interface { Encode(wc io.Writer) error } -type ElementMessageType int - -const ( - Error ElementMessageType = iota + 1 - ChatMessage - Play - Pause - CheckSeek - TooFast - TooSlow - ChangeRate - ChangeSeek - ChangeCurrent - ChangeMovieList - ChangePeopleNum -) - type ElementMessage struct { - Type ElementMessageType `json:"type" yaml:"type"` - Sender string `json:"sender,omitempty" yaml:"sender,omitempty"` - Message string `json:"message,omitempty" yaml:"message,omitempty"` - Seek float64 `json:"seek,omitempty" yaml:"seek,omitempty"` - Rate float64 `json:"rate,omitempty" yaml:"rate,omitempty"` - Current *Current `json:"current,omitempty" yaml:"current,omitempty"` - PeopleNum int64 `json:"peopleNum,omitempty" yaml:"peopleNum,omitempty"` - Time int64 `json:"time,omitempty" yaml:"time,omitempty"` + *pb.ElementMessage } func (em *ElementMessage) MessageType() int { - return websocket.TextMessage + return websocket.BinaryMessage } func (em *ElementMessage) String() string { - out, _ := yaml.Marshal(em) - switch em.Type { - case Error: - return fmt.Sprintf("Element Error: %s", out) - case ChatMessage: - return fmt.Sprintf("Element ChatMessage: %s", out) - case Play: - return fmt.Sprintf("Element Play: %s", out) - case Pause: - return fmt.Sprintf("Element Pause: %s", out) - case CheckSeek: - return fmt.Sprintf("Element CheckSeek: %s", out) - case TooFast: - return fmt.Sprintf("Element TooFast: %s", out) - case TooSlow: - return fmt.Sprintf("Element TooSlow: %s", out) - case ChangeRate: - return fmt.Sprintf("Element ChangeRate: %s", out) - case ChangeSeek: - return fmt.Sprintf("Element ChangeSeek: %s", out) - case ChangeCurrent: - return fmt.Sprintf("Element ChangeCurrent: %s", out) - case ChangeMovieList: - return fmt.Sprintf("Element ChangeMovieList: %s", out) - case ChangePeopleNum: - return fmt.Sprintf("Element ChangePeopleNum: %s", out) - default: - return fmt.Sprintf("Element Unknown: %s", out) - } + // out, _ := yaml.Marshal(em) + // switch em.Type { + // case Error: + // return fmt.Sprintf("Element Error: %s", out) + // case ChatMessage: + // return fmt.Sprintf("Element ChatMessage: %s", out) + // case Play: + // return fmt.Sprintf("Element Play: %s", out) + // case Pause: + // return fmt.Sprintf("Element Pause: %s", out) + // case CheckSeek: + // return fmt.Sprintf("Element CheckSeek: %s", out) + // case TooFast: + // return fmt.Sprintf("Element TooFast: %s", out) + // case TooSlow: + // return fmt.Sprintf("Element TooSlow: %s", out) + // case ChangeRate: + // return fmt.Sprintf("Element ChangeRate: %s", out) + // case ChangeSeek: + // return fmt.Sprintf("Element ChangeSeek: %s", out) + // case ChangeCurrent: + // return fmt.Sprintf("Element ChangeCurrent: %s", out) + // case ChangeMovies: + // return fmt.Sprintf("Element ChangeMovieList: %s", out) + // case ChangePeople: + // return fmt.Sprintf("Element ChangePeopleNum: %s", out) + // default: + // return fmt.Sprintf("Element Unknown: %s", out) + // } + return "" } func (em *ElementMessage) Encode(wc io.Writer) error { - return json.NewEncoder(wc).Encode(em) + b, err := proto.Marshal(em) + if err != nil { + return err + } + _, err = wc.Write(b) + return err } type PingMessage struct{} diff --git a/room/movies.go b/room/movies.go index 3da827f..2679cdc 100644 --- a/room/movies.go +++ b/room/movies.go @@ -29,17 +29,16 @@ type movies struct { // Url will be `PullKey` when Live and Proxy are true type Movie struct { - BaseMovie - PullKey string `json:"pullKey"` - CreateAt int64 `json:"createAt"` - LastEditAt int64 `json:"lastEditAt"` + BaseMovieInfo + PullKey string `json:"pullKey"` + CreatedAt int64 `json:"createAt"` id uint64 channel *rtmps.Channel creator *User } -type BaseMovie struct { +type BaseMovieInfo struct { Url string `json:"url"` Name string `json:"name"` Live bool `json:"live"` @@ -70,7 +69,7 @@ func WithCreator(creator *User) MovieConf { } func NewMovie(id uint64, url, name, type_ string, live, proxy, rtmpSource bool, headers map[string]string, conf ...MovieConf) (*Movie, error) { - return NewMovieWithBaseMovie(id, BaseMovie{ + return NewMovieWithBaseMovie(id, BaseMovieInfo{ Url: url, Name: name, Live: live, @@ -81,13 +80,11 @@ func NewMovie(id uint64, url, name, type_ string, live, proxy, rtmpSource bool, }) } -func NewMovieWithBaseMovie(id uint64, baseMovie BaseMovie, conf ...MovieConf) (*Movie, error) { - now := time.Now().UnixMicro() +func NewMovieWithBaseMovie(id uint64, baseMovie BaseMovieInfo, conf ...MovieConf) (*Movie, error) { m := &Movie{ - id: id, - BaseMovie: baseMovie, - CreateAt: now, - LastEditAt: now, + id: id, + BaseMovieInfo: baseMovie, + CreatedAt: time.Now().UnixMilli(), } m.Init(conf...) return m, m.Check() @@ -151,18 +148,11 @@ func (m *movies) range_(f func(e *dllist.Element[*Movie]) bool) (interrupt bool) } type MovieInfo struct { - Id uint64 `json:"id"` - Url string `json:"url"` - Name string `json:"name"` - Live bool `json:"live"` - Proxy bool `json:"proxy"` - RtmpSource bool `json:"rtmpSource"` - Type string `json:"type"` - Headers map[string]string `json:"headers"` - PullKey string `json:"pullKey"` - CreateAt int64 `json:"createAt"` - LastEditAt int64 `json:"lastEditAt"` - Creator string `json:"creator"` + Id uint64 `json:"id"` + BaseMovieInfo + PullKey string `json:"pullKey"` + CreatedAt int64 `json:"createdAt"` + Creator string `json:"creator"` } func (m *movies) MovieList() (movies []MovieInfo) { @@ -172,17 +162,18 @@ func (m *movies) MovieList() (movies []MovieInfo) { movies = make([]MovieInfo, 0, m.l.Len()) m.range_(func(e *dllist.Element[*Movie]) bool { movies = append(movies, MovieInfo{ - Id: e.Value.id, - Url: e.Value.Url, - Name: e.Value.Name, - Live: e.Value.Live, - Proxy: e.Value.Proxy, - RtmpSource: e.Value.RtmpSource, - Type: e.Value.Type, - Headers: e.Value.Headers, - CreateAt: e.Value.CreateAt, - LastEditAt: e.Value.LastEditAt, - Creator: e.Value.Creator().Name(), + Id: e.Value.id, + BaseMovieInfo: BaseMovieInfo{ + Url: e.Value.Url, + Name: e.Value.Name, + Live: e.Value.Live, + Proxy: e.Value.Proxy, + RtmpSource: e.Value.RtmpSource, + Type: e.Value.Type, + Headers: e.Value.Headers, + }, + CreatedAt: e.Value.CreatedAt, + Creator: e.Value.Creator().Name(), }) return true }) diff --git a/room/room.go b/room/room.go index acdffc2..4eff256 100644 --- a/room/room.go +++ b/room/room.go @@ -25,7 +25,7 @@ type Room struct { password []byte needPassword uint32 version uint64 - current *Current + current *current rtmps *rtmps.Server rtmpa *rtmps.App hidden uint32 @@ -274,7 +274,8 @@ func (r *Room) updateVersion() uint64 { } func (r *Room) Current() *Current { - return r.current + c := r.current.Current() + return &c } // Seek will be set to 0 @@ -285,18 +286,19 @@ func (r *Room) ChangeCurrentMovie(id uint64) error { return err } r.current.SetMovie(MovieInfo{ - Id: e.Value.id, - Url: e.Value.Url, - Name: e.Value.Name, - Live: e.Value.Live, - Proxy: e.Value.Proxy, - RtmpSource: e.Value.RtmpSource, - Type: e.Value.Type, - Headers: e.Value.Headers, - PullKey: e.Value.PullKey, - CreateAt: e.Value.CreateAt, - LastEditAt: e.Value.LastEditAt, - Creator: e.Value.Creator().Name(), + Id: e.Value.id, + BaseMovieInfo: BaseMovieInfo{ + Url: e.Value.Url, + Name: e.Value.Name, + Live: e.Value.Live, + Proxy: e.Value.Proxy, + RtmpSource: e.Value.RtmpSource, + Type: e.Value.Type, + Headers: e.Value.Headers, + }, + PullKey: e.Value.PullKey, + CreatedAt: e.Value.CreatedAt, + Creator: e.Value.Creator().Name(), }) return nil } diff --git a/room/user.go b/room/user.go index 7afe3e8..49154ac 100644 --- a/room/user.go +++ b/room/user.go @@ -7,6 +7,7 @@ import ( "time" "github.com/gorilla/websocket" + pb "github.com/synctv-org/synctv/proto" "github.com/zijiren233/gencontainer/dllist" "github.com/zijiren233/stream" "golang.org/x/crypto/bcrypt" @@ -143,7 +144,7 @@ func (u *User) SetAdmin(admin bool) { } func (u *User) NewMovie(url string, name string, type_ string, live bool, proxy bool, rtmpSource bool, headers map[string]string, conf ...MovieConf) (*Movie, error) { - return u.NewMovieWithBaseMovie(BaseMovie{ + return u.NewMovieWithBaseMovie(BaseMovieInfo{ Url: url, Name: name, Live: live, @@ -154,11 +155,11 @@ func (u *User) NewMovie(url string, name string, type_ string, live bool, proxy }, conf...) } -func (u *User) NewMovieWithBaseMovie(baseMovie BaseMovie, conf ...MovieConf) (*Movie, error) { +func (u *User) NewMovieWithBaseMovie(baseMovie BaseMovieInfo, conf ...MovieConf) (*Movie, error) { return NewMovieWithBaseMovie(atomic.AddUint64(&u.room.mid, 1), baseMovie, append(conf, WithCreator(u))...) } -func (u *User) Movie(id uint64) (*MovieInfo, error) { +func (u *User) Movie(id uint64) (*pb.MovieInfo, error) { u.room.movies.lock.RLock() defer u.room.movies.lock.RUnlock() @@ -166,7 +167,7 @@ func (u *User) Movie(id uint64) (*MovieInfo, error) { if err != nil { return nil, err } - movie := &MovieInfo{ + movie := &pb.MovieInfo{ Id: m.Id(), Url: m.Url, Name: m.Name, @@ -176,8 +177,7 @@ func (u *User) Movie(id uint64) (*MovieInfo, error) { Type: m.Type, Headers: m.Headers, PullKey: m.PullKey, - CreateAt: m.CreateAt, - LastEditAt: m.LastEditAt, + CreatedAt: m.CreatedAt, Creator: m.Creator().Name(), } if movie.Proxy && u.name != movie.Creator { @@ -186,13 +186,13 @@ func (u *User) Movie(id uint64) (*MovieInfo, error) { return movie, nil } -func (u *User) MovieList() []*MovieInfo { +func (u *User) MovieList() []*pb.MovieInfo { u.room.movies.lock.RLock() defer u.room.movies.lock.RUnlock() - movies := make([]*MovieInfo, 0, u.room.movies.l.Len()) + movies := make([]*pb.MovieInfo, 0, u.room.movies.l.Len()) u.room.movies.range_(func(e *dllist.Element[*Movie]) bool { - m := &MovieInfo{ + m := &pb.MovieInfo{ Id: e.Value.Id(), Url: e.Value.Url, Name: e.Value.Name, @@ -202,8 +202,7 @@ func (u *User) MovieList() []*MovieInfo { Type: e.Value.Type, Headers: e.Value.Headers, PullKey: e.Value.PullKey, - CreateAt: e.Value.CreateAt, - LastEditAt: e.Value.LastEditAt, + CreatedAt: e.Value.CreatedAt, Creator: e.Value.Creator().Name(), } if e.Value.Proxy && u.name != m.Creator { diff --git a/server/handlers/api-movie.go b/server/handlers/api-movie.go index 133590a..c8e9857 100644 --- a/server/handlers/api-movie.go +++ b/server/handlers/api-movie.go @@ -17,6 +17,7 @@ import ( "github.com/google/uuid" json "github.com/json-iterator/go" "github.com/synctv-org/synctv/internal/conf" + pb "github.com/synctv-org/synctv/proto" "github.com/synctv-org/synctv/room" "github.com/synctv-org/synctv/utils" "github.com/zijiren233/livelib/av" @@ -97,7 +98,7 @@ func Movies(ctx *gin.Context) { })) } -type PushMovieReq = room.BaseMovie +type PushMovieReq = room.BaseMovieInfo func PushMovie(ctx *gin.Context) { user, err := AuthRoom(ctx.GetHeader("Authorization")) @@ -219,8 +220,10 @@ func PushMovie(ctx *gin.Context) { } if err := user.Broadcast(&room.ElementMessage{ - Type: room.ChangeMovieList, - Sender: user.Name(), + ElementMessage: &pb.ElementMessage{ + Type: pb.ElementMessageType_CHANGE_MOVIES, + Sender: user.Name(), + }, }, room.WithSendToSelf()); err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, NewApiErrorResp(err)) return @@ -318,8 +321,10 @@ func EditMovie(ctx *gin.Context) { m.Headers = req.Headers if err := user.Broadcast(&room.ElementMessage{ - Type: room.ChangeMovieList, - Sender: user.Name(), + ElementMessage: &pb.ElementMessage{ + Type: pb.ElementMessageType_CHANGE_MOVIES, + Sender: user.Name(), + }, }, room.WithSendToSelf()); err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, NewApiErrorResp(err)) return @@ -351,8 +356,10 @@ func DelMovie(ctx *gin.Context) { } if err := user.Broadcast(&room.ElementMessage{ - Type: room.ChangeMovieList, - Sender: user.Name(), + ElementMessage: &pb.ElementMessage{ + Type: pb.ElementMessageType_CHANGE_MOVIES, + Sender: user.Name(), + }, }, room.WithSendToSelf()); err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, NewApiErrorResp(err)) return @@ -374,8 +381,10 @@ func ClearMovies(ctx *gin.Context) { } if err := user.Broadcast(&room.ElementMessage{ - Type: room.ChangeMovieList, - Sender: user.Name(), + ElementMessage: &pb.ElementMessage{ + Type: pb.ElementMessageType_CHANGE_MOVIES, + Sender: user.Name(), + }, }, room.WithSendToSelf()); err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, NewApiErrorResp(err)) return @@ -408,8 +417,10 @@ func SwapMovie(ctx *gin.Context) { } if err := user.Broadcast(&room.ElementMessage{ - Type: room.ChangeMovieList, - Sender: user.Name(), + ElementMessage: &pb.ElementMessage{ + Type: pb.ElementMessageType_CHANGE_MOVIES, + Sender: user.Name(), + }, }, room.WithSendToSelf()); err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, NewApiErrorResp(err)) return @@ -439,11 +450,12 @@ func ChangeCurrentMovie(ctx *gin.Context) { ctx.AbortWithStatusJSON(http.StatusBadRequest, NewApiErrorResp(err)) return } - if err := user.Broadcast(&room.ElementMessage{ - Type: room.ChangeCurrent, - Sender: user.Name(), - Current: user.Room().Current(), + ElementMessage: &pb.ElementMessage{ + Type: pb.ElementMessageType_CHANGE_CURRENT, + Sender: user.Name(), + Current: user.Room().Current().Proto(), + }, }, room.WithSendToSelf()); err != nil { ctx.AbortWithStatusJSON(http.StatusInternalServerError, NewApiErrorResp(err)) return @@ -499,7 +511,7 @@ func ProxyMovie(ctx *gin.Context) { if err != nil { ctx.AbortWithStatusJSON(http.StatusBadRequest, NewApiErrorResp(err)) } - cm := room.Current().Movie() + cm := room.Current().Movie if !cm.Proxy || cm.Live { ctx.AbortWithStatusJSON(http.StatusBadRequest, NewApiErrorStringResp("not support proxy")) return diff --git a/server/handlers/api-room.go b/server/handlers/api-room.go index 31bdbb1..89fdb9e 100644 --- a/server/handlers/api-room.go +++ b/server/handlers/api-room.go @@ -15,6 +15,7 @@ import ( "github.com/golang-jwt/jwt/v5" "github.com/maruel/natural" "github.com/synctv-org/synctv/internal/conf" + pb "github.com/synctv-org/synctv/proto" "github.com/synctv-org/synctv/room" "github.com/zijiren233/gencontainer/vec" rtmps "github.com/zijiren233/livelib/server" @@ -173,8 +174,10 @@ func NewCreateRoomHandler(s *rtmps.Server) gin.HandlerFunc { current := r.ClientNum() if current != pre { if err := r.Broadcast(&room.ElementMessage{ - Type: room.ChangePeopleNum, - PeopleNum: current, + ElementMessage: &pb.ElementMessage{ + Type: pb.ElementMessageType_CHANGE_PEOPLE, + PeopleNum: current, + }, }); err != nil { log.Errorf("ws: room %s broadcast people num error: %v", r.ID(), err) continue diff --git a/server/handlers/websocket.go b/server/handlers/websocket.go index 00e06ea..07dd5ff 100644 --- a/server/handlers/websocket.go +++ b/server/handlers/websocket.go @@ -1,15 +1,18 @@ package handlers import ( + "io" "net/http" "time" json "github.com/json-iterator/go" + "google.golang.org/protobuf/proto" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" log "github.com/sirupsen/logrus" "github.com/synctv-org/synctv/cmd/flags" + pb "github.com/synctv-org/synctv/proto" "github.com/synctv-org/synctv/room" "github.com/synctv-org/synctv/utils" ) @@ -34,8 +37,10 @@ func NewWSMessageHandler(u *room.User) func(c *websocket.Conn) error { if err != nil { log.Errorf("ws: register client error: %v", err) b, err := json.Marshal(room.ElementMessage{ - Type: room.Error, - Message: err.Error(), + ElementMessage: &pb.ElementMessage{ + Type: pb.ElementMessageType_ERROR, + Message: err.Error(), + }, }) if err != nil { return err @@ -78,7 +83,7 @@ func handleWriterMessage(c *room.Client) error { func handleReaderMessage(c *room.Client) error { defer c.Close() - var timeDiff float64 + var msg pb.ElementMessage for { t, rd, err := c.NextReader() if err != nil { @@ -94,100 +99,143 @@ func handleReaderMessage(c *room.Client) error { log.Infof("ws: room %s user %s receive close message", c.Room().ID(), c.Username()) } return nil - case websocket.TextMessage: - msg := room.ElementMessage{} - if err := json.NewDecoder(rd).Decode(&msg); err != nil { - log.Errorf("ws: room %s user %s decode message error: %v", c.Room().ID(), c.Username(), err) + case websocket.BinaryMessage: + var data []byte + if data, err = io.ReadAll(rd); err != nil { + log.Errorf("ws: room %s user %s read message error: %v", c.Room().ID(), c.Username(), err) if err := c.Send(&room.ElementMessage{ - Type: room.Error, - Message: err.Error(), + ElementMessage: &pb.ElementMessage{ + Type: pb.ElementMessageType_ERROR, + Message: err.Error(), + }, }); err != nil { log.Errorf("ws: room %s user %s send error message error: %v", c.Room().ID(), c.Username(), err) return err } continue } - if flags.Dev { - log.Infof("ws: receive room %s user %s message: %+v", c.Room().ID(), c.Username(), msg) - } - if msg.Time != 0 { - timeDiff = time.Since(time.UnixMilli(msg.Time)).Seconds() - } else { - timeDiff = 0.0 - } - if timeDiff < 0 { - timeDiff = 0 - } else if timeDiff > 1.5 { - timeDiff = 1.5 - } - switch msg.Type { - case room.ChatMessage: - if len(msg.Message) > 4096 { - c.Send(&room.ElementMessage{ - Type: room.Error, - Message: "message too long", - }) - continue + if err := proto.Unmarshal(data, &msg); err != nil { + log.Errorf("ws: room %s user %s decode message error: %v", c.Room().ID(), c.Username(), err) + if err := c.Send(&room.ElementMessage{ + ElementMessage: &pb.ElementMessage{ + Type: pb.ElementMessageType_ERROR, + Message: err.Error(), + }, + }); err != nil { + log.Errorf("ws: room %s user %s send error message error: %v", c.Room().ID(), c.Username(), err) + return err } - c.Broadcast(&room.ElementMessage{ - Type: room.ChatMessage, - Sender: c.Username(), - Message: msg.Message, - }, room.WithSendToSelf()) - case room.Play: - status := c.Room().SetStatus(true, msg.Seek, msg.Rate, timeDiff) - c.Broadcast(&room.ElementMessage{ - Type: room.Play, - Sender: c.Username(), - Seek: status.Seek, - Rate: status.Rate, - }) - case room.Pause: - status := c.Room().SetStatus(false, msg.Seek, msg.Rate, timeDiff) - c.Broadcast(&room.ElementMessage{ - Type: room.Pause, - Sender: c.Username(), - Seek: status.Seek, - Rate: status.Rate, - }) - case room.ChangeRate: - status := c.Room().SetSeekRate(msg.Seek, msg.Rate, timeDiff) - c.Broadcast(&room.ElementMessage{ - Type: room.ChangeRate, - Sender: c.Username(), - Seek: status.Seek, - Rate: status.Rate, - }) - case room.ChangeSeek: - status := c.Room().SetSeekRate(msg.Seek, msg.Rate, timeDiff) - c.Broadcast(&room.ElementMessage{ - Type: room.ChangeSeek, - Sender: c.Username(), - Seek: status.Seek, - Rate: status.Rate, - }) - case room.CheckSeek: - status := c.Room().Current().Status() - if status.Seek+maxInterval < msg.Seek+timeDiff { - c.Send(&room.ElementMessage{ - Type: room.TooFast, - Seek: status.Seek, - Rate: status.Rate, - }) - } else if status.Seek-maxInterval > msg.Seek+timeDiff { - c.Send(&room.ElementMessage{ - Type: room.TooSlow, - Seek: status.Seek, - Rate: status.Rate, - }) - } else { - c.Send(&room.ElementMessage{ - Type: room.CheckSeek, - Seek: status.Seek, - Rate: status.Rate, - }) + continue + } + case websocket.TextMessage: + if err := json.NewDecoder(rd).Decode(&msg); err != nil { + log.Errorf("ws: room %s user %s decode message error: %v", c.Room().ID(), c.Username(), err) + if err := c.Send(&room.ElementMessage{ + ElementMessage: &pb.ElementMessage{ + Type: pb.ElementMessageType_ERROR, + Message: err.Error(), + }, + }); err != nil { + log.Errorf("ws: room %s user %s send error message error: %v", c.Room().ID(), c.Username(), err) + return err } + continue } } + if flags.Dev { + log.Infof("ws: receive room %s user %s message: %+v", c.Room().ID(), c.Username(), msg.String()) + } + if err := handleElementMsg(c.Room(), &msg, func(em *pb.ElementMessage) error { + em.Sender = c.Username() + return c.Send(&room.ElementMessage{ElementMessage: em}) + }, func(em *pb.ElementMessage, bc ...room.BroadcastConf) error { + em.Sender = c.Username() + return c.Broadcast(&room.ElementMessage{ElementMessage: em}, bc...) + }); err != nil { + log.Errorf("ws: room %s user %s handle message error: %v", c.Room().ID(), c.Username(), err) + return err + } + } +} + +type send func(*pb.ElementMessage) error + +type broadcast func(*pb.ElementMessage, ...room.BroadcastConf) error + +func handleElementMsg(r *room.Room, msg *pb.ElementMessage, send send, broadcast broadcast) error { + var timeDiff float64 + if msg.Time != 0 { + timeDiff = time.Since(time.UnixMilli(msg.Time)).Seconds() + } else { + timeDiff = 0.0 + } + if timeDiff < 0 { + timeDiff = 0 + } else if timeDiff > 1.5 { + timeDiff = 1.5 + } + switch msg.Type { + case pb.ElementMessageType_CHAT_MESSAGE: + if len(msg.Message) > 4096 { + send(&pb.ElementMessage{ + Type: pb.ElementMessageType_ERROR, + Message: "message too long", + }) + return nil + } + broadcast(&pb.ElementMessage{ + Type: pb.ElementMessageType_CHAT_MESSAGE, + Message: msg.Message, + }, room.WithSendToSelf()) + case pb.ElementMessageType_PLAY: + status := r.SetStatus(true, msg.Seek, msg.Rate, timeDiff) + broadcast(&pb.ElementMessage{ + Type: pb.ElementMessageType_PLAY, + Seek: status.Seek, + Rate: status.Rate, + }) + case pb.ElementMessageType_PAUSE: + status := r.SetStatus(false, msg.Seek, msg.Rate, timeDiff) + broadcast(&pb.ElementMessage{ + Type: pb.ElementMessageType_PAUSE, + Seek: status.Seek, + Rate: status.Rate, + }) + case pb.ElementMessageType_CHANGE_RATE: + status := r.SetSeekRate(msg.Seek, msg.Rate, timeDiff) + broadcast(&pb.ElementMessage{ + Type: pb.ElementMessageType_CHANGE_RATE, + Seek: status.Seek, + Rate: status.Rate, + }) + case pb.ElementMessageType_CHANGE_SEEK: + status := r.SetSeekRate(msg.Seek, msg.Rate, timeDiff) + broadcast(&pb.ElementMessage{ + Type: pb.ElementMessageType_CHANGE_SEEK, + Seek: status.Seek, + Rate: status.Rate, + }) + case pb.ElementMessageType_CHECK_SEEK: + status := r.Current().Status + if status.Seek+maxInterval < msg.Seek+timeDiff { + send(&pb.ElementMessage{ + Type: pb.ElementMessageType_TOO_FAST, + Seek: status.Seek, + Rate: status.Rate, + }) + } else if status.Seek-maxInterval > msg.Seek+timeDiff { + 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, + }) + } } + return nil }