mirror of
https://github.com/AynaLivePlayer/blivedm-go.git
synced 2025-12-06 11:22:50 +08:00
@@ -15,6 +15,7 @@ import (
|
||||
type Client struct {
|
||||
conn *websocket.Conn
|
||||
roomID string
|
||||
realRoomID string
|
||||
token string
|
||||
host string
|
||||
eventHandlers *eventHandlers
|
||||
@@ -36,15 +37,18 @@ func NewClient(roomID string) *Client {
|
||||
|
||||
func (c *Client) Connect() error {
|
||||
rid, _ := strconv.Atoi(c.roomID)
|
||||
if rid <= 1000 {
|
||||
if rid <= 1000 && c.realRoomID == "" {
|
||||
realID, err := api.GetRoomRealID(c.roomID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.roomID = realID
|
||||
c.realRoomID = realID
|
||||
} else {
|
||||
c.realRoomID = c.roomID
|
||||
}
|
||||
if c.host == "" {
|
||||
info, err := api.GetDanmuInfo(c.roomID)
|
||||
info, err := api.GetDanmuInfo(c.realRoomID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -67,31 +71,33 @@ retry:
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) Start() {
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-c.done:
|
||||
log.Debug("current client closed")
|
||||
return
|
||||
default:
|
||||
msgType, data, err := c.conn.ReadMessage()
|
||||
if err != nil {
|
||||
time.Sleep(time.Duration(3) * time.Millisecond)
|
||||
_ = c.Connect()
|
||||
continue
|
||||
}
|
||||
if msgType != websocket.BinaryMessage {
|
||||
log.Error("packet not binary", data)
|
||||
continue
|
||||
}
|
||||
for _, pkt := range packet.DecodePacket(data).Parse() {
|
||||
go c.Handle(pkt)
|
||||
}
|
||||
func (c *Client) listen() {
|
||||
for {
|
||||
select {
|
||||
case <-c.done:
|
||||
log.Debug("current client closed")
|
||||
return
|
||||
default:
|
||||
msgType, data, err := c.conn.ReadMessage()
|
||||
if err != nil {
|
||||
time.Sleep(time.Duration(3) * time.Millisecond)
|
||||
_ = c.Connect()
|
||||
continue
|
||||
}
|
||||
if msgType != websocket.BinaryMessage {
|
||||
log.Error("packet not binary", data)
|
||||
continue
|
||||
}
|
||||
for _, pkt := range packet.DecodePacket(data).Parse() {
|
||||
go c.Handle(pkt)
|
||||
}
|
||||
}
|
||||
}()
|
||||
go c.startHeartBeat()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) Start() {
|
||||
go c.listen()
|
||||
go c.heartBeat()
|
||||
}
|
||||
|
||||
func (c *Client) Stop() {
|
||||
@@ -114,7 +120,7 @@ func (c *Client) UseDefaultHost() {
|
||||
c.SetHost("wss://broadcastlv.chat.bilibili.com/sub")
|
||||
}
|
||||
|
||||
func (c *Client) startHeartBeat() {
|
||||
func (c *Client) heartBeat() {
|
||||
pkt := packet.NewHeartBeatPacket()
|
||||
for {
|
||||
select {
|
||||
@@ -130,7 +136,7 @@ func (c *Client) startHeartBeat() {
|
||||
}
|
||||
|
||||
func (c *Client) sendEnterPacket() error {
|
||||
rid, err := strconv.Atoi(c.roomID)
|
||||
rid, err := strconv.Atoi(c.realRoomID)
|
||||
if err != nil {
|
||||
return errors.New("error roomID")
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -61,6 +62,11 @@ func (c *Client) Handle(p packet.Packet) {
|
||||
case packet.Notification:
|
||||
sb := bytes.NewBuffer(p.Body).String()
|
||||
cmd := gjson.Get(sb, "cmd").String()
|
||||
// 新的弹幕 cmd 可能带参数
|
||||
if strings.Contains(cmd, ":") {
|
||||
index := strings.Index(cmd, ":")
|
||||
cmd = cmd[:index]
|
||||
}
|
||||
// 优先执行自定义 eventHandler ,会覆盖库内自带的 handler
|
||||
f, ok := (*c.customEventHandlers)[cmd]
|
||||
if ok {
|
||||
|
||||
1
go.mod
1
go.mod
@@ -6,6 +6,5 @@ require (
|
||||
github.com/andybalholm/brotli v1.0.4
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816
|
||||
github.com/tidwall/gjson v1.13.0
|
||||
)
|
||||
|
||||
6
go.sum
6
go.sum
@@ -4,23 +4,17 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816 h1:J6v8awz+me+xeb/cUTotKgceAYouhIB3pjzgRd6IlGk=
|
||||
github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816/go.mod h1:tzym/CEb5jnFI+Q0k4Qq3+LvRF4gO3E2pxS8fHP8jcA=
|
||||
github.com/tidwall/gjson v1.13.0 h1:3TFY9yxOQShrvmjdM76K+jc66zJeT6D3/VFFYCGQf7M=
|
||||
github.com/tidwall/gjson v1.13.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package message
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"github.com/Akegarasu/blivedm-go/utils"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
@@ -60,15 +59,15 @@ type (
|
||||
)
|
||||
|
||||
func (d *Danmaku) Parse(data []byte) {
|
||||
sb := bytes.NewBuffer(data).String()
|
||||
info := gjson.Get(sb, "info")
|
||||
sb := utils.BytesToString(data)
|
||||
info := gjson.Parse(sb).Get("info")
|
||||
ext := new(Extra)
|
||||
emo := new(Emoticon)
|
||||
err := json.Unmarshal([]byte(info.Get("0.15.extra").String()), ext)
|
||||
err := utils.UnmarshalString(info.Get("0.15.extra").String(), ext)
|
||||
if err != nil {
|
||||
log.Error("parse danmuku extra failed")
|
||||
}
|
||||
err = json.Unmarshal([]byte(info.Get("0.13").String()), emo)
|
||||
err = utils.UnmarshalString(info.Get("0.13").String(), emo)
|
||||
if err != nil {
|
||||
log.Error("parse danmuku emoticon failed")
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package message
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"github.com/Akegarasu/blivedm-go/utils"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
@@ -111,9 +110,9 @@ type ComboSend struct {
|
||||
}
|
||||
|
||||
func (g *Gift) Parse(data []byte) {
|
||||
sb := bytes.NewBuffer(data).String()
|
||||
sb := utils.BytesToString(data)
|
||||
sd := gjson.Get(sb, "data").String()
|
||||
err := json.Unmarshal([]byte(sd), g)
|
||||
err := utils.UnmarshalString(sd, g)
|
||||
if err != nil {
|
||||
log.Error("parse Gift failed")
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package message
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"github.com/Akegarasu/blivedm-go/utils"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
@@ -20,9 +19,9 @@ type GuardBuy struct {
|
||||
}
|
||||
|
||||
func (g *GuardBuy) Parse(data []byte) {
|
||||
sb := bytes.NewBuffer(data).String()
|
||||
sb := utils.BytesToString(data)
|
||||
sd := gjson.Get(sb, "data").String()
|
||||
err := json.Unmarshal([]byte(sd), g)
|
||||
err := utils.UnmarshalString(sd, g)
|
||||
if err != nil {
|
||||
log.Error("parse GuardBuy failed")
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package message
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"github.com/Akegarasu/blivedm-go/utils"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
@@ -72,9 +71,9 @@ type SuperChat struct {
|
||||
}
|
||||
|
||||
func (s *SuperChat) Parse(data []byte) {
|
||||
sb := bytes.NewBuffer(data).String()
|
||||
sb := utils.BytesToString(data)
|
||||
sd := gjson.Get(sb, "data").String()
|
||||
err := json.Unmarshal([]byte(sd), s)
|
||||
err := utils.UnmarshalString(sd, s)
|
||||
if err != nil {
|
||||
log.Error("parse superchat failed")
|
||||
}
|
||||
|
||||
7
utils/json.go
Normal file
7
utils/json.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package utils
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
func UnmarshalString(str string, v interface{}) error {
|
||||
return json.Unmarshal(StringToBytes(str), v)
|
||||
}
|
||||
18
utils/strconv.go
Normal file
18
utils/strconv.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func StringToBytes(s string) []byte {
|
||||
return *(*[]byte)(unsafe.Pointer(
|
||||
&struct {
|
||||
string
|
||||
Cap int
|
||||
}{s, len(s)},
|
||||
))
|
||||
}
|
||||
|
||||
func BytesToString(b []byte) string {
|
||||
return *(*string)(unsafe.Pointer(&b))
|
||||
}
|
||||
Reference in New Issue
Block a user