refactor: 接入官方弹幕API,同时兼容原野生API。修改了协议文件

main
NorthLan 3 years ago
parent 169ab93840
commit 76008c7098

@ -4,12 +4,15 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"git.noahlan.cn/northlan/ntools-go/logger" "git.noahlan.cn/northlan/ntools-go/logger"
"github.com/go-ping/ping"
"github.com/pkg/errors"
"io/ioutil" "io/ioutil"
"live-gateway/bilibili/msg_handler" "live-gateway/bilibili/msg_handler"
"live-gateway/config" "live-gateway/config"
"live-gateway/live" "live-gateway/live"
"live-gateway/ws" "live-gateway/ws"
"net/http" "net/http"
"strconv"
"strings" "strings"
"time" "time"
) )
@ -22,28 +25,21 @@ type MsgHandler interface {
// 实现 live.Handler 接口 // 实现 live.Handler 接口
var _ live.Handler = (*LiveBilibili)(nil) var _ live.Handler = (*LiveBilibili)(nil)
type LiveBilibili struct { type (
Url string LiveBilibili struct {
GetRoomUrl string *live.Live
RoomId int64 sequenceId uint32
UserId int64
HeartbeatInterval time.Duration // 心跳间
RoomInfo *RoomInfo roomInfo *RoomInfo // 房间信息
Live *live.Live webSocketInfo *WebsocketInfoResp // ws信息
msgHandlerMapper map[string]MsgHandler msgHandlerMapper map[string]MsgHandler
entered chan struct{} // 进入房间 entered chan struct{} // 进入房间
} }
)
func NewLiveBilibili() *live.Live { func NewLiveBilibili() *LiveBilibili {
cfg := &config.Config.Bilibili
bl := &LiveBilibili{ bl := &LiveBilibili{
Url: cfg.Url,
GetRoomUrl: cfg.GetRoomUrl,
RoomId: cfg.RoomId,
UserId: cfg.UserId,
HeartbeatInterval: cfg.HeartbeatInterval * time.Second,
msgHandlerMapper: make(map[string]MsgHandler, 6), msgHandlerMapper: make(map[string]MsgHandler, 6),
entered: make(chan struct{}), entered: make(chan struct{}),
} }
@ -53,36 +49,93 @@ func NewLiveBilibili() *live.Live {
ws.WithPacker(NewPackBilibili()), ws.WithPacker(NewPackBilibili()),
), ),
) )
l.PreConnect(bl.preConnect)
l.Init(bl.Init) l.Init(bl.Init)
l.PreConnect(bl.PreConnect)
l.Handler(bl) l.Handler(bl)
bl.Live = l bl.Live = l
return l return bl
} }
func (l *LiveBilibili) AddMessageHandler(h ...MsgHandler) { func (l *LiveBilibili) registerMessageHandler(h ...MsgHandler) {
for _, handler := range h { for _, handler := range h {
l.msgHandlerMapper[handler.CMD()] = handler l.msgHandlerMapper[handler.CMD()] = handler
} }
} }
func (l *LiveBilibili) PreConnect() (url string, err error) { func (l *LiveBilibili) preConnect() (url string, err error) {
url = l.Url cfg := config.Config.Bilibili
// 避免重复请求接口 if err = l.initRoomInfo(); err != nil {
if l.RoomInfo != nil && return "", err
(l.RoomId == l.RoomInfo.RoomId || l.RoomId == l.RoomInfo.ShortId) { }
switch cfg.Type {
case config.BilibiliTypeOfficial:
err = l.initWebsocketInfo()
if err != nil {
logger.SLog.Errorf("获取wss信息失败, err:%+v", err)
return "", err
}
if len(l.webSocketInfo.Ip) == 0 || len(l.webSocketInfo.WssPort) == 0 {
return "", errors.New("获取到的wss信息中地址或端口为空")
}
logger.SLog.Info("正在寻找连接最快的API地址...")
// 获取最快的地址
var minDuration = 1 * time.Hour
var minIdx = 0
for i, ip := range l.webSocketInfo.Host {
pinger, err := ping.NewPinger(ip)
if err != nil {
continue
}
pinger.SetPrivileged(true)
pinger.Count = 3
pinger.Interval = 100 * time.Nanosecond // 100ns /time
pinger.Timeout = 200 * time.Millisecond // 200ms
err = pinger.Run()
if err != nil {
continue
}
stat := pinger.Statistics()
if stat.AvgRtt < minDuration {
minDuration = stat.AvgRtt
minIdx = i
}
}
url = fmt.Sprintf("wss://%s:%d/sub", l.webSocketInfo.Host[minIdx], l.webSocketInfo.WssPort[0])
logger.SLog.Info("找到当前最快的弹幕服务器地址 ", url, " 延迟:", minDuration)
l.registerMessageHandler(
msg_handler.NewDanmakuOfficialHandler(l.roomInfo.RoomId),
msg_handler.NewGuardBuyOfficialHandler(l.roomInfo.RoomId),
msg_handler.NewGiftOfficialHandler(l.roomInfo.RoomId),
)
case config.BilibiliTypeCustom:
url = cfg.Custom.Url
l.registerMessageHandler(
msg_handler.NewDanmakuHandler(l.roomInfo.RoomId),
msg_handler.NewSendGiftHandler(l.roomInfo.RoomId),
msg_handler.NewGuardBuyHandler(l.roomInfo.RoomId),
//&msg_handler.InterActWordHandler{},
)
}
return return
} }
fetchUrl := fmt.Sprintf(`%s%d`, l.GetRoomUrl, l.RoomId) func (l *LiveBilibili) initRoomInfo() error {
response, err := http.Get(fetchUrl) // 避免重复请求接口
if l.roomInfo != nil {
return nil
}
cfg := config.Config.Bilibili
response, err := http.Get(fmt.Sprintf(`%s%d`, cfg.GetRoomUrl, cfg.RoomId))
if err != nil { if err != nil {
return "", err return err
} }
res, err := ioutil.ReadAll(response.Body) res, err := ioutil.ReadAll(response.Body)
if err != nil { if err != nil {
return "", err return err
} }
var getRoomInfoResp struct { var getRoomInfoResp struct {
Code int `json:"code"` Code int `json:"code"`
@ -92,32 +145,86 @@ func (l *LiveBilibili) PreConnect() (url string, err error) {
} }
err = json.Unmarshal(res, &getRoomInfoResp) err = json.Unmarshal(res, &getRoomInfoResp)
if err != nil { if err != nil {
return "", err return err
} }
l.RoomInfo = getRoomInfoResp.Data l.roomInfo = getRoomInfoResp.Data
logger.SLog.Infof("获取房间数据: %+v\n", l.RoomInfo) logger.SLog.Infof("获取房间数据: %+v\n", l.roomInfo)
//log.With("获取房间数据", l.RoomInfo)
// 获取房间信息后再添加消息处理器 是因为需要房间号 return nil
l.AddMessageHandler( }
msg_handler.NewDanmakuHandler(l.RoomInfo.RoomId),
msg_handler.NewSendGiftHandler(l.RoomInfo.RoomId), func (l *LiveBilibili) initWebsocketInfo() error {
msg_handler.NewGuardBuyHandler(l.RoomInfo.RoomId), cfg := config.Config.Bilibili
//&msg_handler.InterActWordHandler{},
) req := &WebsocketInfoReq{
return RoomId: l.roomInfo.RoomId,
}
content, _ := json.Marshal(req)
header := &CommonHeader{
ContentType: JsonType,
ContentAcceptType: JsonType,
Timestamp: strconv.FormatInt(time.Now().Unix(), 10),
SignatureMethod: HmacSha256,
SignatureVersion: BiliVersion,
Authorization: "",
Nonce: strconv.FormatInt(time.Now().UnixNano(), 10),
AccessKeyId: cfg.Official.AkId,
ContentMD5: Md5(string(content)),
}
header.Authorization = CreateSignature(header, cfg.Official.AkSecret)
request, err := http.NewRequest("POST", fmt.Sprintf("%s/v1/common/websocketInfo", cfg.Official.Api), strings.NewReader(string(content)))
if err != nil {
return err
}
for k, v := range header.ToMap() {
request.Header.Add(k, v)
}
response, err := http.DefaultClient.Do(request)
if err != nil {
return err
}
res, err := ioutil.ReadAll(response.Body)
if err != nil {
return err
}
var baseResp BaseResp
err = json.Unmarshal(res, &baseResp)
if err != nil {
return err
}
if baseResp.Code != 0 {
return errors.New(fmt.Sprintf("调用API失败, result: %+v", baseResp))
}
var infoData WebsocketInfoResp
err = json.Unmarshal(baseResp.Data, &infoData)
if err != nil {
return err
}
l.webSocketInfo = &infoData
logger.SLog.Debugf("获取到wss信息为: %+v", infoData)
return nil
} }
func (l *LiveBilibili) Init(conn *ws.NWebsocket) (err error) { func (l *LiveBilibili) Init(conn *ws.NWebsocket) (err error) {
cfg := config.Config.Bilibili
switch cfg.Type {
case config.BilibiliTypeOfficial:
if err = l.auth(conn); err != nil {
logger.SLog.Error(err)
return
}
case config.BilibiliTypeCustom:
if err = l.joinRoom(conn); err != nil { if err = l.joinRoom(conn); err != nil {
logger.SLog.Error(err) logger.SLog.Error(err)
return return
} }
}
// 等待进入房间 // 等待进入房间或登录成功
<-l.entered <-l.entered
go l.heartbeat(conn, l.HeartbeatInterval) go l.heartbeat(conn, cfg.HeartbeatInterval*time.Second)
return return
} }
@ -129,7 +236,7 @@ func (l *LiveBilibili) HandlerMessage(v interface{}) {
} }
// 处理消息 // 处理消息
switch entry.operation { switch entry.operation {
case WsOpEnterRoomSuccess: case WsOpEnterRoomOrAuthReply:
go func() { go func() {
select { select {
case l.entered <- struct{}{}: case l.entered <- struct{}{}:
@ -160,12 +267,29 @@ func (l *LiveBilibili) HandlerMessage(v interface{}) {
} }
} }
func (l *LiveBilibili) auth(conn *ws.NWebsocket) error {
if l.webSocketInfo == nil {
return errors.New("websocket信息未获取成功不能登录")
}
data := &WsEntry{
operation: WsOpEnterRoomOrAuth,
data: []byte(l.webSocketInfo.AuthBody),
}
l.sequenceId++
err := conn.SendBinaryMessage(data)
if err != nil {
return errors.Wrap(err, "发送AUTH消息到wss失败")
}
return nil
}
func (l *LiveBilibili) joinRoom(conn *ws.NWebsocket) error { func (l *LiveBilibili) joinRoom(conn *ws.NWebsocket) error {
cfg := config.Config.Bilibili
msg := JoinRoomReq{ msg := JoinRoomReq{
Platform: "web", Platform: "web",
ProtoVer: 1, ProtoVer: 1,
RoomId: l.RoomInfo.RoomId, RoomId: l.roomInfo.RoomId,
Uid: l.UserId, Uid: cfg.UserId,
Type: 2, Type: 2,
} }
body, err := json.Marshal(msg) body, err := json.Marshal(msg)
@ -175,7 +299,7 @@ func (l *LiveBilibili) joinRoom(conn *ws.NWebsocket) error {
data := &WsEntry{ data := &WsEntry{
protoVer: 0, protoVer: 0,
operation: WsOpEnterRoom, operation: WsOpEnterRoomOrAuth,
sequenceId: WsHeaderDefaultSequence, sequenceId: WsHeaderDefaultSequence,
data: body, data: body,
} }
@ -191,9 +315,10 @@ func (l *LiveBilibili) heartbeat(conn *ws.NWebsocket, t time.Duration) {
data := &WsEntry{ data := &WsEntry{
protoVer: 0, protoVer: 0,
operation: WsOpHeartbeat, operation: WsOpHeartbeat,
sequenceId: WsHeaderDefaultSequence, sequenceId: l.sequenceId,
data: nil, data: nil,
} }
l.sequenceId++
err := conn.SendBinaryMessage(data) err := conn.SendBinaryMessage(data)
if err != nil { if err != nil {
return return

@ -1,12 +1,14 @@
package bilibili package bilibili
import "encoding/json"
// ws-ops // ws-ops
const ( const (
WsOpHeartbeat = 2 // 心跳 WsOpHeartbeat = 2 // 心跳
WsOpHeartbeatReply = 3 // 心跳回应 WsOpHeartbeatReply = 3 // 心跳回应
WsOpMessage = 5 // 弹幕消息等 WsOpMessage = 5 // 弹幕消息等
WsOpEnterRoom = 7 // 请求进入房间 WsOpEnterRoomOrAuth = 7 // 请求进入房间
WsOpEnterRoomSuccess = 8 // 进房回应 WsOpEnterRoomOrAuthReply = 8 // 进房回应
) )
// version protocol // version protocol
@ -54,6 +56,28 @@ type JoinRoomReq struct {
Key string `json:"key"` Key string `json:"key"`
} }
// BaseResp 基础API返回
type BaseResp struct {
Code int64 `json:"code"`
Message string `json:"message"`
RequestId string `json:"request_id"`
Data json.RawMessage `json:"data"`
}
type WebsocketInfoReq struct {
RoomId int64 `json:"room_id"`
}
// WebsocketInfoResp 官方websocket信息回复
type WebsocketInfoResp struct {
Ip []string `json:"ip"`
AuthBody string `json:"auth_body"`
Host []string `json:"host"`
TcpPort []int64 `json:"tcp_port"`
WsPort []int64 `json:"ws_port"`
WssPort []int64 `json:"wss_port"`
}
type CMD struct { type CMD struct {
CMD string `json:"cmd"` CMD string `json:"cmd"`
} }

@ -18,3 +18,18 @@ type FansMedal struct {
Special string `json:"special"` // ??? Special string `json:"special"` // ???
TargetId int `json:"target_id"` // 佩戴勋章所指的主播ID TargetId int `json:"target_id"` // 佩戴勋章所指的主播ID
} }
const (
CoinTypeGold = "gold"
CoinTypeSilver = "silver"
)
func IsPaidGift(coinType string) bool {
if coinType == CoinTypeGold {
return true
}
if coinType == CoinTypeSilver {
return false
}
return false
}

@ -118,8 +118,8 @@ func (d *DanmakuHandler) HandlerMessage(data []byte) {
LiveRoomId: d.liveRoomId, LiveRoomId: d.liveRoomId,
Uid: dm.UID, Uid: dm.UID,
Uname: dm.Uname, Uname: dm.Uname,
Content: dm.Content, Msg: dm.Content,
SendTime: dm.SendTime, Timestamp: dm.SendTime,
} }
_ = d.producer.SendMessageAsync(dmMsg, strconv.FormatInt(dm.UID, 10)) _ = d.producer.SendMessageAsync(dmMsg, strconv.FormatInt(dm.UID, 10))

@ -0,0 +1,77 @@
package msg_handler
import (
"encoding/json"
"git.noahlan.cn/northlan/ntools-go/kafka"
"git.noahlan.cn/northlan/ntools-go/logger"
"live-gateway/config"
pbMq "live-gateway/pb"
kfk "live-gateway/pkg/kafka"
"strconv"
)
//var _ bilibili.MsgHandler = (*DanmakuHandler)(nil)
// DanmakuOfficial 弹幕结构 官方
type DanmakuOfficial struct {
Uname string `json:"uname"` // 用户昵称
UID int64 `json:"uid"` // 用户ID
UFace string `json:"uface"` // 用户头像
Timestamp int64 `json:"timestamp"` // 弹幕发送时间秒级时间戳
RoomId int64 `json:"room_id"` // 用户模式
Msg string `json:"msg"` // 弹幕内容
MsgId string `json:"msg_id"` // 消息唯一ID
GuardLevel int64 `json:"guard_level"` // 对应房间大航海等级
FansMedalWearingStatus bool `json:"fans_medal_wearing_status"` // 当前佩戴粉丝勋章佩戴状态
FansMedalName string `json:"fans_medal_name"` // 粉丝勋章名
FansMedalLevel int64 `json:"fans_medal_level"` // 粉丝勋章等级
}
type DanmakuOfficialHandler struct {
producer *kafka.Producer
liveRoomId int64
}
func NewDanmakuOfficialHandler(liveRoomId int64) *DanmakuOfficialHandler {
cfg := config.Config.Kafka.Danmaku
return &DanmakuOfficialHandler{
producer: kafka.NewKafkaProducer(kfk.DefaultProducerConfig, cfg.Addr, cfg.Topic),
liveRoomId: liveRoomId,
}
}
func (d *DanmakuOfficialHandler) CMD() string {
return "LIVE_OPEN_PLATFORM_DM"
}
func (d *DanmakuOfficialHandler) HandlerMessage(data []byte) {
var baseMsg struct {
CMD string `json:"cmd"`
Data *DanmakuOfficial `json:"data"`
}
if err := json.Unmarshal(data, &baseMsg); err != nil {
return
}
dm := baseMsg.Data
logger.SLog.Debugf("%s 说: %s", dm.Uname, dm.Msg)
logger.SLog.Debugf("%+v", dm)
dmMsg := &pbMq.MqDanmaku{
Platform: pbMq.Platform_name[int32(pbMq.Platform_bilibili)],
LiveRoomId: d.liveRoomId,
Uid: dm.UID,
Uname: dm.Uname,
Avatar: dm.UFace,
Msg: dm.Msg,
MsgId: dm.MsgId,
Timestamp: dm.Timestamp,
NobilityLevel: dm.GuardLevel,
FansMedalWearingStatus: dm.FansMedalWearingStatus,
FansMedalName: dm.FansMedalName,
FansMedalLevel: dm.FansMedalLevel,
}
_ = d.producer.SendMessageAsync(dmMsg, strconv.FormatInt(dm.UID, 10))
}

@ -0,0 +1,98 @@
package msg_handler
import (
"encoding/json"
"git.noahlan.cn/northlan/ntools-go/kafka"
"live-gateway/config"
"live-gateway/pb"
kfk "live-gateway/pkg/kafka"
"strconv"
)
// GiftOfficial 礼物结构 官方
type GiftOfficial struct {
RoomId int64 `json:"room_id"` // 房间号
Uid int64 `json:"uid"` // 送礼用户UID
Uname string `json:"uname"` // 送礼用户昵称
Uface string `json:"uface"` // 送礼用户头像
GiftId int64 `json:"gift_id"` // 道具id(盲盒:爆出道具id)
GiftName string `json:"gift_name"` // 道具名(盲盒:爆出道具名)
GiftNum int64 `json:"gift_num"` // 赠送道具数量
Price int64 `json:"price"` // 支付金额(1000 = 1元 = 10电池),盲盒:爆出道具的价值
Paid bool `json:"paid"` // 是否是付费道具
FansMedalLevel int64 `json:"fans_medal_level"` // 实际送礼人的勋章信息
FansMedalName string `json:"fans_medal_name"` // 粉丝勋章名
FansMedalWearingStatus bool `json:"fans_medal_wearing_status"` // 当前佩戴的粉丝勋章佩戴状态
GuardLevel int64 `json:"guard_level"` // 大航海等级
Timestamp int64 `json:"timestamp"` // 收礼时间秒级时间戳
AnchorInfo anchorInfo `json:"anchor_info"` // 主播信息
MsgId string `json:"msg_id"` // 消息唯一id
}
type anchorInfo struct {
Uid int64 `json:"uid"` // 收礼主播uid
Uname string `json:"uname"` // 收礼主播昵称
Uface string `json:"uface"` // 收礼主播头像
}
type GiftOfficialHandler struct {
producer *kafka.Producer
liveRoomId int64
}
func NewGiftOfficialHandler(liveRoomId int64) *GiftOfficialHandler {
cfg := config.Config.Kafka.Gift
return &GiftOfficialHandler{
producer: kafka.NewKafkaProducer(kfk.DefaultProducerConfig, cfg.Addr, cfg.Topic),
liveRoomId: liveRoomId,
}
}
func (h *GiftOfficialHandler) CMD() string {
return "LIVE_OPEN_PLATFORM_SEND_GIFT"
}
func (h *GiftOfficialHandler) HandlerMessage(data []byte) {
var baseMsg struct {
CMD string `json:"cmd"`
Data *GiftOfficial `json:"data"`
}
if err := json.Unmarshal(data, &baseMsg); err != nil {
return
}
//logger.SLog.Infof("%s %s礼物 %s x%d", baseMsg.Data.Uname, baseMsg.Data.Action, baseMsg.Data.GiftName, baseMsg.Data.Num)
gift := baseMsg.Data
dmMsg := &pbMq.MqGift{
Platform: pbMq.Platform_name[int32(pbMq.Platform_bilibili)],
LiveRoomId: h.liveRoomId,
Uid: gift.Uid,
Uname: gift.Uname,
Avatar: gift.Uface,
GiftId: gift.GiftId,
GiftName: gift.GiftName,
GiftNum: gift.GiftNum,
Price: gift.Price,
IsPaid: gift.Paid,
MsgId: gift.MsgId,
Timestamp: gift.Timestamp,
NobilityLevel: gift.GuardLevel,
FansMedalWearingStatus: gift.FansMedalWearingStatus,
FansMedalName: gift.FansMedalName,
FansMedalLevel: gift.FansMedalLevel,
}
_ = h.producer.SendMessageAsync(dmMsg, strconv.FormatInt(dmMsg.Uid, 10))
}
func (h *GiftOfficialHandler) isPaid(coinType string) bool {
if coinType == CoinTypeGold {
return true
}
if coinType == CoinTypeSilver {
return false
}
return false
}

@ -13,7 +13,7 @@ import (
type GuardBuy struct { type GuardBuy struct {
Uid int64 `json:"uid"` // 用户ID Uid int64 `json:"uid"` // 用户ID
Uname string `json:"username"` // 用户名 Uname string `json:"username"` // 用户名
GuardLevel int32 `json:"guard_level"` // 等级(3舰长 1总督) GuardLevel int64 `json:"guard_level"` // 等级(3舰长 1总督)
Num int32 `json:"num"` // 数量 Num int32 `json:"num"` // 数量
Price int64 `json:"price"` // 价格 金瓜子 Price int64 `json:"price"` // 价格 金瓜子
GiftId int64 `json:"gift_id"` // 礼物ID GiftId int64 `json:"gift_id"` // 礼物ID
@ -50,16 +50,13 @@ func (h *GuardBuyHandler) HandlerMessage(data []byte) {
logger.SLog.Infof("%s 购买 %s x %d", baseMsg.Data.Uname, baseMsg.Data.GiftName, baseMsg.Data.Num) logger.SLog.Infof("%s 购买 %s x %d", baseMsg.Data.Uname, baseMsg.Data.GiftName, baseMsg.Data.Num)
dmMsg := &pbMq.MqGuardBuy{ dmMsg := &pbMq.MqNobilityBuy{
Platform: pbMq.Platform_name[int32(pbMq.Platform_bilibili)], Platform: pbMq.Platform_name[int32(pbMq.Platform_bilibili)],
LiveRoomId: h.liveRoomId, LiveRoomId: h.liveRoomId,
Uid: baseMsg.Data.Uid, Uid: baseMsg.Data.Uid,
Uname: baseMsg.Data.Uname, Uname: baseMsg.Data.Uname,
GuardLevel: baseMsg.Data.GuardLevel, NobilityLevel: baseMsg.Data.GuardLevel,
Num: baseMsg.Data.Num,
Price: baseMsg.Data.Price, Price: baseMsg.Data.Price,
GiftId: baseMsg.Data.GiftId,
GiftName: baseMsg.Data.GiftName,
StartTime: baseMsg.Data.StartTime, StartTime: baseMsg.Data.StartTime,
EndTime: baseMsg.Data.EndTime, EndTime: baseMsg.Data.EndTime,
} }

@ -0,0 +1,98 @@
package msg_handler
import (
"encoding/json"
"git.noahlan.cn/northlan/ntools-go/kafka"
"git.noahlan.cn/northlan/ntools-go/logger"
"github.com/jinzhu/now"
"live-gateway/config"
"live-gateway/pb"
kfk "live-gateway/pkg/kafka"
"live-gateway/pkg/timex"
"strconv"
)
type GuardBuyOfficial struct {
UserInfo userInfo `json:"user_info"` // 用户信息
GuardLevel int64 `json:"guard_level"` // 大航海等级 1总督 2提督 3舰长
GuardNum int64 `json:"guard_num"` // 大航海数量
GuardUnit string `json:"guard_unit"` // 大航海单位 (个月)
FansMedalLevel int64 `json:"fans_medal_level"` // 粉丝勋章等级
FansMedalName string `json:"fans_medal_name"` // 粉丝勋章名
FansMedalWearingStatus bool `json:"fans_medal_wearing_status"` // 佩戴的粉丝勋章佩戴状态
RoomId int64 `json:"room_id"` // 房间号
MsgId string `json:"msg_id"` // 消息唯一id
Timestamp int64 `json:"timestamp"` // 上舰时间秒级时间戳
}
type userInfo struct {
Uid int64 `json:"uid"` // 用户uid
Uname string `json:"uname"` // 用户昵称
Uface string `json:"uface"` // 用户头像
}
type GuardBuyOfficialHandler struct {
producer *kafka.Producer
liveRoomId int64
}
func NewGuardBuyOfficialHandler(liveRoomId int64) *GuardBuyOfficialHandler {
cfg := config.Config.Kafka.GuardBuy
return &GuardBuyOfficialHandler{
producer: kafka.NewKafkaProducer(kfk.DefaultProducerConfig, cfg.Addr, cfg.Topic),
liveRoomId: liveRoomId,
}
}
func (h *GuardBuyOfficialHandler) CMD() string {
return "GUARD_BUY"
}
func (h *GuardBuyOfficialHandler) HandlerMessage(data []byte) {
var baseMsg struct {
CMD string `json:"cmd"`
Data *GuardBuyOfficial `json:"data"`
}
if err := json.Unmarshal(data, &baseMsg); err != nil {
return
}
d := baseMsg.Data
logger.SLog.Infof("%s 购买 %d %d%s", d.UserInfo.Uname, d.GuardLevel, d.GuardNum, d.GuardUnit)
dmMsg := &pbMq.MqNobilityBuy{
Platform: pbMq.Platform_name[int32(pbMq.Platform_bilibili)],
LiveRoomId: h.liveRoomId,
Uid: d.UserInfo.Uid,
Uname: d.UserInfo.Uname,
Avatar: d.UserInfo.Uface,
MsgId: d.MsgId,
NobilityLevel: d.GuardLevel,
Price: 0, // 自己算
StartTime: d.Timestamp,
EndTime: 0, // 自己算
FansMedalWearingStatus: d.FansMedalWearingStatus,
FansMedalName: d.FansMedalName,
FansMedalLevel: d.FansMedalLevel,
}
switch d.GuardLevel {
case 1:
dmMsg.Price = 19998 * 1000 // 金瓜子
case 2:
dmMsg.Price = 1998 * 1000
case 3:
dmMsg.Price = 138 * 1000 // 应该没有人会不用连续包月然后取消吧?
}
// 计算时间
switch d.GuardUnit {
case "月":
dmMsg.EndTime = now.With(timex.TimestampToTime(d.Timestamp)).
AddDate(0, 1, 0).Unix()
case "年":
dmMsg.EndTime = now.With(timex.TimestampToTime(d.Timestamp)).
AddDate(1, 0, 0).Unix()
}
_ = h.producer.SendMessageAsync(dmMsg, strconv.FormatInt(dmMsg.Uid, 10))
}

@ -0,0 +1,14 @@
package msg_handler
import (
"fmt"
"github.com/jinzhu/now"
"live-gateway/pkg/timex"
"testing"
)
func TestTime(t *testing.T) {
fmt.Println(timex.TimestampToTime(1653555128))
last := now.BeginningOfDay().AddDate(0, 1, 0)
fmt.Println(last, last.Unix(), last.UnixMilli(), last.UnixMicro(), last.UnixNano())
}

@ -42,7 +42,7 @@ type SendGift struct {
NameColor string `json:"name_color"` // 名 颜色 NameColor string `json:"name_color"` // 名 颜色
Num int64 `json:"num"` // 数量 Num int64 `json:"num"` // 数量
OriginalGiftName string `json:"original_gift_name"` // 原始礼物名称??? OriginalGiftName string `json:"original_gift_name"` // 原始礼物名称???
Price int `json:"price"` // 价格? 但不是电池 Price int64 `json:"price"` // 价格? 但不是电池
RCost int `json:"rcost"` // ??? RCost int `json:"rcost"` // ???
Remain int `json:"remain"` // 用户道具包裹剩余数量 Remain int `json:"remain"` // 用户道具包裹剩余数量
Rnd string `json:"rnd"` // 随机数? Rnd string `json:"rnd"` // 随机数?
@ -53,18 +53,13 @@ type SendGift struct {
SuperGiftNum int `json:"super_gift_num"` // ??? SuperGiftNum int `json:"super_gift_num"` // ???
SvgaBlock int `json:"svga_block"` // ??? SvgaBlock int `json:"svga_block"` // ???
TagImage string `json:"tag_image"` // ??? TagImage string `json:"tag_image"` // ???
Timestamp int `json:"timestamp"` // 赠送时间 Timestamp int64 `json:"timestamp"` // 赠送时间
TopList interface{} `json:"top_list"` // ??? TopList interface{} `json:"top_list"` // ???
TotalCoin int `json:"total_coin"` // 总值 瓜子数 TotalCoin int `json:"total_coin"` // 总值 瓜子数
Uid int `json:"uid"` // 用户ID Uid int `json:"uid"` // 用户ID
Uname string `json:"uname"` // 用户名 Uname string `json:"uname"` // 用户名
} }
const (
CoinTypeGold = "gold"
CoinTypeSilver = "silver"
)
type SendGiftHandler struct { type SendGiftHandler struct {
producer *kafka.Producer producer *kafka.Producer
liveRoomId int64 liveRoomId int64
@ -98,22 +93,19 @@ func (h *SendGiftHandler) HandlerMessage(data []byte) {
LiveRoomId: h.liveRoomId, LiveRoomId: h.liveRoomId,
Uid: int64(baseMsg.Data.Uid), Uid: int64(baseMsg.Data.Uid),
Uname: baseMsg.Data.Uname, Uname: baseMsg.Data.Uname,
Avatar: "",
GiftId: baseMsg.Data.GiftId, GiftId: baseMsg.Data.GiftId,
Num: baseMsg.Data.Num,
GiftName: baseMsg.Data.GiftName, GiftName: baseMsg.Data.GiftName,
Price: int64(baseMsg.Data.Price), GiftNum: baseMsg.Data.Num,
IsPaid: h.isPaid(baseMsg.Data.CoinType), Price: baseMsg.Data.Price,
IsPaid: IsPaidGift(baseMsg.Data.CoinType),
MsgId: "",
Timestamp: baseMsg.Data.Timestamp,
NobilityLevel: 0,
FansMedalWearingStatus: false,
FansMedalName: "",
FansMedalLevel: 0,
} }
_ = h.producer.SendMessageAsync(dmMsg, strconv.FormatInt(dmMsg.Uid, 10)) _ = h.producer.SendMessageAsync(dmMsg, strconv.FormatInt(dmMsg.Uid, 10))
} }
func (h *SendGiftHandler) isPaid(coinType string) bool {
if coinType == CoinTypeGold {
return true
}
if coinType == CoinTypeSilver {
return false
}
return false
}

@ -0,0 +1,97 @@
package bilibili
import (
"crypto/hmac"
"crypto/md5"
"crypto/sha256"
"encoding/hex"
"fmt"
"sort"
"strings"
)
const AcceptHeader = "Accept"
const ContentTypeHeader = "Content-Type"
const AuthorizationHeader = "Authorization"
const JsonType = "application/json"
const BiliVersion = "1.0"
const HmacSha256 = "HMAC-SHA256"
const BiliTimestampHeader = "x-bili-timestamp"
const BiliSignatureMethodHeader = "x-bili-signature-method"
const BiliSignatureNonceHeader = "x-bili-signature-nonce"
const BiliAccessKeyIdHeader = "x-bili-accesskeyid"
const BiliSignVersionHeader = "x-bili-signature-version"
const BiliContentMD5Header = "x-bili-content-md5"
//CreateSignature 生成Authorization加密串
func CreateSignature(header *CommonHeader, accessKeySecret string) string {
sStr := header.ToSortedString()
return HmacSHA256(accessKeySecret, sStr)
}
func Md5(str string) (md5str string) {
data := []byte(str)
has := md5.Sum(data)
md5str = fmt.Sprintf("%x", has)
return md5str
}
func HmacSHA256(key string, data string) string {
mac := hmac.New(sha256.New, []byte(key))
mac.Write([]byte(data))
return hex.EncodeToString(mac.Sum(nil))
}
type CommonHeader struct {
ContentType string
ContentAcceptType string
Timestamp string
SignatureMethod string
SignatureVersion string
Authorization string
Nonce string
AccessKeyId string
ContentMD5 string
}
// ToMap 所有字段转map<string, string>
func (h *CommonHeader) ToMap() map[string]string {
return map[string]string{
BiliTimestampHeader: h.Timestamp,
BiliSignatureMethodHeader: h.SignatureMethod,
BiliSignatureNonceHeader: h.Nonce,
BiliAccessKeyIdHeader: h.AccessKeyId,
BiliSignVersionHeader: h.SignatureVersion,
BiliContentMD5Header: h.ContentMD5,
AuthorizationHeader: h.Authorization,
ContentTypeHeader: h.ContentType,
AcceptHeader: h.ContentAcceptType,
}
}
// ToSortMap 参与加密的字段转map<string, string>
func (h *CommonHeader) ToSortMap() map[string]string {
return map[string]string{
BiliTimestampHeader: h.Timestamp,
BiliSignatureMethodHeader: h.SignatureMethod,
BiliSignatureNonceHeader: h.Nonce,
BiliAccessKeyIdHeader: h.AccessKeyId,
BiliSignVersionHeader: h.SignatureVersion,
BiliContentMD5Header: h.ContentMD5,
}
}
//ToSortedString 生成需要加密的文本
func (h *CommonHeader) ToSortedString() (sign string) {
hMap := h.ToSortMap()
var hSil []string
for k := range hMap {
hSil = append(hSil, k)
}
sort.Strings(hSil)
for _, v := range hSil {
sign += v + ":" + hMap[v] + "\n"
}
sign = strings.TrimRight(sign, "\n")
return
}

@ -1,10 +1,16 @@
Bilibili: Bilibili:
Enabled: true Enabled: true
Type: official
Official:
Api: https://live-open.biliapi.com
AkId: 1rVL1YRSoii28LJ1O7KIQqqQ
AkSecret: 5USwZt2bygTIE8a2cXahZrzsdKtbxd
Custom:
Url: wss://broadcastlv.chat.bilibili.com:2245/sub Url: wss://broadcastlv.chat.bilibili.com:2245/sub
GetRoomUrl: https://api.live.bilibili.com/room/v1/Room/room_init?id= GetRoomUrl: https://api.live.bilibili.com/room/v1/Room/room_init?id=
HeartbeatInterval: 30 HeartbeatInterval: 30
UserId: 111222 UserId: 111222
RoomId: 8722013 RoomId: 6925399
Log: Log:
Console: Console:
Level: debug Level: debug

@ -10,6 +10,13 @@ import (
var Config config var Config config
type BilibiliType string
const (
BilibiliTypeOfficial BilibiliType = "official"
BilibiliTypeCustom BilibiliType = "custom"
)
type ( type (
Kafka struct { Kafka struct {
Addr []string Addr []string
@ -18,7 +25,15 @@ type (
config struct { config struct {
Bilibili struct { Bilibili struct {
Enabled bool // 是否启用 Enabled bool // 是否启用
Type BilibiliType // 类型
Official struct {
Api string // API 地址
AkId string // accessKeyId
AkSecret string // accessSecret
} // 官方API
Custom struct {
Url string // 弹幕服务器url Url string // 弹幕服务器url
}
GetRoomUrl string // 获取房间信息url GetRoomUrl string // 获取房间信息url
RoomId int64 // 待连接roomId RoomId int64 // 待连接roomId
UserId int64 // 用于连接的userId,0则随机生成 UserId int64 // 用于连接的userId,0则随机生成

@ -19,7 +19,9 @@ require (
github.com/eapache/go-resiliency v1.2.0 // indirect github.com/eapache/go-resiliency v1.2.0 // indirect
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect
github.com/eapache/queue v1.1.0 // indirect github.com/eapache/queue v1.1.0 // indirect
github.com/go-ping/ping v1.1.0 // indirect
github.com/golang/snappy v0.0.4 // indirect github.com/golang/snappy v0.0.4 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gookit/goutil v0.5.0 // indirect github.com/gookit/goutil v0.5.0 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/imdario/mergo v0.3.12 // indirect github.com/imdario/mergo v0.3.12 // indirect
@ -28,6 +30,7 @@ require (
github.com/jcmturner/gofork v1.0.0 // indirect github.com/jcmturner/gofork v1.0.0 // indirect
github.com/jcmturner/gokrb5/v8 v8.4.2 // indirect github.com/jcmturner/gokrb5/v8 v8.4.2 // indirect
github.com/jcmturner/rpc/v2 v2.0.3 // indirect github.com/jcmturner/rpc/v2 v2.0.3 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/klauspost/compress v1.15.1 // indirect github.com/klauspost/compress v1.15.1 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect
@ -39,7 +42,8 @@ require (
go.uber.org/multierr v1.8.0 // indirect go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.21.0 // indirect go.uber.org/zap v1.21.0 // indirect
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
golang.org/x/net v0.0.0-20220421235706-1d1ef9303861 // indirect golang.org/x/net v0.0.0-20220531201128-c960675eff93 // indirect
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
) )

@ -32,6 +32,8 @@ github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/frankban/quicktest v1.14.2 h1:SPb1KFFmM+ybpEjPUhCCkZOM5xlovT5UbrMvWnXyBns= github.com/frankban/quicktest v1.14.2 h1:SPb1KFFmM+ybpEjPUhCCkZOM5xlovT5UbrMvWnXyBns=
github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
github.com/go-ping/ping v1.1.0 h1:3MCGhVX4fyEUuhsfwPrsEdQw6xspHkv5zHsiSoDFZYw=
github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk=
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@ -44,6 +46,9 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gookit/color v1.5.0 h1:1Opow3+BWDwqor78DcJkJCIwnkviFi+rrOANki9BUFw= github.com/gookit/color v1.5.0 h1:1Opow3+BWDwqor78DcJkJCIwnkviFi+rrOANki9BUFw=
github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo=
github.com/gookit/config/v2 v2.1.0 h1:RNiT4tsAkDBP5QPhxGk/vEcQO4ET1xdRBd9BStL4G1E= github.com/gookit/config/v2 v2.1.0 h1:RNiT4tsAkDBP5QPhxGk/vEcQO4ET1xdRBd9BStL4G1E=
@ -76,6 +81,8 @@ github.com/jcmturner/gokrb5/v8 v8.4.2 h1:6ZIM6b/JJN0X8UM43ZOM6Z4SJzla+a/u7scXFJz
github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc=
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
@ -168,19 +175,25 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220421235706-1d1ef9303861 h1:yssD99+7tqHWO5Gwh81phT+67hg+KttniBr6UnEXOY8= golang.org/x/net v0.0.0-20220421235706-1d1ef9303861 h1:yssD99+7tqHWO5Gwh81phT+67hg+KttniBr6UnEXOY8=
golang.org/x/net v0.0.0-20220421235706-1d1ef9303861/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220421235706-1d1ef9303861/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220531201128-c960675eff93 h1:MYimHLfoXEpOhqd/zgoA/uoXzHB86AEky4LAx5ij9xA=
golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -189,6 +202,8 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=

@ -28,7 +28,7 @@ func main() {
bLive := bilibili.NewLiveBilibili() bLive := bilibili.NewLiveBilibili()
go func() { go func() {
if err := bLive.Serve(); err != nil { if err := bLive.Serve(); err != nil {
logger.SLog.Error("err", err) logger.SLog.Error("err: ", err)
wg.Done() wg.Done()
} }
}() }()

@ -72,26 +72,28 @@ func (Platform) EnumDescriptor() ([]byte, []int) {
return file_mq_proto_rawDescGZIP(), []int{0} return file_mq_proto_rawDescGZIP(), []int{0}
} }
type MqGuardBuy struct { type MqNobilityBuy struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Platform string `protobuf:"bytes,1,opt,name=platform,proto3" json:"platform,omitempty"` Platform string `protobuf:"bytes,1,opt,name=platform,proto3" json:"platform,omitempty"` // 平台
LiveRoomId int64 `protobuf:"varint,2,opt,name=liveRoomId,proto3" json:"liveRoomId,omitempty"` LiveRoomId int64 `protobuf:"varint,2,opt,name=liveRoomId,proto3" json:"liveRoomId,omitempty"` // 直播间ID
Uid int64 `protobuf:"varint,3,opt,name=uid,proto3" json:"uid,omitempty"` Uid int64 `protobuf:"varint,3,opt,name=uid,proto3" json:"uid,omitempty"` // 用户ID
Uname string `protobuf:"bytes,4,opt,name=uname,proto3" json:"uname,omitempty"` Uname string `protobuf:"bytes,4,opt,name=uname,proto3" json:"uname,omitempty"` // 用户名
GuardLevel int32 `protobuf:"varint,5,opt,name=guardLevel,proto3" json:"guardLevel,omitempty"` Avatar string `protobuf:"bytes,5,opt,name=avatar,proto3" json:"avatar,omitempty"` // 头像
Num int32 `protobuf:"varint,6,opt,name=num,proto3" json:"num,omitempty"` MsgId string `protobuf:"bytes,6,opt,name=msgId,proto3" json:"msgId,omitempty"` // 消息唯一ID
Price int64 `protobuf:"varint,7,opt,name=price,proto3" json:"price,omitempty"` NobilityLevel int64 `protobuf:"varint,7,opt,name=nobilityLevel,proto3" json:"nobilityLevel,omitempty"` // 贵族等级
GiftId int64 `protobuf:"varint,8,opt,name=giftId,proto3" json:"giftId,omitempty"` Price int64 `protobuf:"varint,8,opt,name=price,proto3" json:"price,omitempty"` // 平台price
GiftName string `protobuf:"bytes,9,opt,name=giftName,proto3" json:"giftName,omitempty"` StartTime int64 `protobuf:"varint,9,opt,name=startTime,proto3" json:"startTime,omitempty"` // 开始时间
StartTime int64 `protobuf:"varint,10,opt,name=startTime,proto3" json:"startTime,omitempty"` EndTime int64 `protobuf:"varint,10,opt,name=endTime,proto3" json:"endTime,omitempty"` // 过期时间
EndTime int64 `protobuf:"varint,11,opt,name=endTime,proto3" json:"endTime,omitempty"` FansMedalWearingStatus bool `protobuf:"varint,11,opt,name=fansMedalWearingStatus,proto3" json:"fansMedalWearingStatus,omitempty"` // 牌子佩戴状态
} FansMedalName string `protobuf:"bytes,12,opt,name=fansMedalName,proto3" json:"fansMedalName,omitempty"` // 粉丝牌子名
FansMedalLevel int64 `protobuf:"varint,13,opt,name=fansMedalLevel,proto3" json:"fansMedalLevel,omitempty"` // 粉丝牌子等级
func (x *MqGuardBuy) Reset() { }
*x = MqGuardBuy{}
func (x *MqNobilityBuy) Reset() {
*x = MqNobilityBuy{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_mq_proto_msgTypes[0] mi := &file_mq_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -99,13 +101,13 @@ func (x *MqGuardBuy) Reset() {
} }
} }
func (x *MqGuardBuy) String() string { func (x *MqNobilityBuy) String() string {
return protoimpl.X.MessageStringOf(x) return protoimpl.X.MessageStringOf(x)
} }
func (*MqGuardBuy) ProtoMessage() {} func (*MqNobilityBuy) ProtoMessage() {}
func (x *MqGuardBuy) ProtoReflect() protoreflect.Message { func (x *MqNobilityBuy) ProtoReflect() protoreflect.Message {
mi := &file_mq_proto_msgTypes[0] mi := &file_mq_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -117,84 +119,98 @@ func (x *MqGuardBuy) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x) return mi.MessageOf(x)
} }
// Deprecated: Use MqGuardBuy.ProtoReflect.Descriptor instead. // Deprecated: Use MqNobilityBuy.ProtoReflect.Descriptor instead.
func (*MqGuardBuy) Descriptor() ([]byte, []int) { func (*MqNobilityBuy) Descriptor() ([]byte, []int) {
return file_mq_proto_rawDescGZIP(), []int{0} return file_mq_proto_rawDescGZIP(), []int{0}
} }
func (x *MqGuardBuy) GetPlatform() string { func (x *MqNobilityBuy) GetPlatform() string {
if x != nil { if x != nil {
return x.Platform return x.Platform
} }
return "" return ""
} }
func (x *MqGuardBuy) GetLiveRoomId() int64 { func (x *MqNobilityBuy) GetLiveRoomId() int64 {
if x != nil { if x != nil {
return x.LiveRoomId return x.LiveRoomId
} }
return 0 return 0
} }
func (x *MqGuardBuy) GetUid() int64 { func (x *MqNobilityBuy) GetUid() int64 {
if x != nil { if x != nil {
return x.Uid return x.Uid
} }
return 0 return 0
} }
func (x *MqGuardBuy) GetUname() string { func (x *MqNobilityBuy) GetUname() string {
if x != nil { if x != nil {
return x.Uname return x.Uname
} }
return "" return ""
} }
func (x *MqGuardBuy) GetGuardLevel() int32 { func (x *MqNobilityBuy) GetAvatar() string {
if x != nil { if x != nil {
return x.GuardLevel return x.Avatar
} }
return 0 return ""
}
func (x *MqNobilityBuy) GetMsgId() string {
if x != nil {
return x.MsgId
}
return ""
} }
func (x *MqGuardBuy) GetNum() int32 { func (x *MqNobilityBuy) GetNobilityLevel() int64 {
if x != nil { if x != nil {
return x.Num return x.NobilityLevel
} }
return 0 return 0
} }
func (x *MqGuardBuy) GetPrice() int64 { func (x *MqNobilityBuy) GetPrice() int64 {
if x != nil { if x != nil {
return x.Price return x.Price
} }
return 0 return 0
} }
func (x *MqGuardBuy) GetGiftId() int64 { func (x *MqNobilityBuy) GetStartTime() int64 {
if x != nil { if x != nil {
return x.GiftId return x.StartTime
} }
return 0 return 0
} }
func (x *MqGuardBuy) GetGiftName() string { func (x *MqNobilityBuy) GetEndTime() int64 {
if x != nil { if x != nil {
return x.GiftName return x.EndTime
} }
return "" return 0
} }
func (x *MqGuardBuy) GetStartTime() int64 { func (x *MqNobilityBuy) GetFansMedalWearingStatus() bool {
if x != nil { if x != nil {
return x.StartTime return x.FansMedalWearingStatus
} }
return 0 return false
} }
func (x *MqGuardBuy) GetEndTime() int64 { func (x *MqNobilityBuy) GetFansMedalName() string {
if x != nil { if x != nil {
return x.EndTime return x.FansMedalName
}
return ""
}
func (x *MqNobilityBuy) GetFansMedalLevel() int64 {
if x != nil {
return x.FansMedalLevel
} }
return 0 return 0
} }
@ -204,12 +220,18 @@ type MqDanmaku struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Platform string `protobuf:"bytes,1,opt,name=platform,proto3" json:"platform,omitempty"` Platform string `protobuf:"bytes,1,opt,name=platform,proto3" json:"platform,omitempty"` // 平台
LiveRoomId int64 `protobuf:"varint,2,opt,name=liveRoomId,proto3" json:"liveRoomId,omitempty"` LiveRoomId int64 `protobuf:"varint,2,opt,name=liveRoomId,proto3" json:"liveRoomId,omitempty"` // 直播间ID
Uid int64 `protobuf:"varint,3,opt,name=uid,proto3" json:"uid,omitempty"` Uid int64 `protobuf:"varint,3,opt,name=uid,proto3" json:"uid,omitempty"` // 用户ID
Uname string `protobuf:"bytes,4,opt,name=uname,proto3" json:"uname,omitempty"` Uname string `protobuf:"bytes,4,opt,name=uname,proto3" json:"uname,omitempty"` // 用户名
Content string `protobuf:"bytes,5,opt,name=content,proto3" json:"content,omitempty"` Avatar string `protobuf:"bytes,5,opt,name=avatar,proto3" json:"avatar,omitempty"` // 头像
SendTime int64 `protobuf:"varint,6,opt,name=sendTime,proto3" json:"sendTime,omitempty"` Msg string `protobuf:"bytes,6,opt,name=msg,proto3" json:"msg,omitempty"` // 内容
MsgId string `protobuf:"bytes,7,opt,name=msgId,proto3" json:"msgId,omitempty"` // 消息唯一ID
Timestamp int64 `protobuf:"varint,8,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // 发送时间
NobilityLevel int64 `protobuf:"varint,9,opt,name=nobilityLevel,proto3" json:"nobilityLevel,omitempty"` // 贵族等级
FansMedalWearingStatus bool `protobuf:"varint,10,opt,name=fansMedalWearingStatus,proto3" json:"fansMedalWearingStatus,omitempty"` // 牌子佩戴状态
FansMedalName string `protobuf:"bytes,11,opt,name=fansMedalName,proto3" json:"fansMedalName,omitempty"` // 粉丝牌子名
FansMedalLevel int64 `protobuf:"varint,12,opt,name=fansMedalLevel,proto3" json:"fansMedalLevel,omitempty"` // 粉丝牌子等级
} }
func (x *MqDanmaku) Reset() { func (x *MqDanmaku) Reset() {
@ -272,16 +294,58 @@ func (x *MqDanmaku) GetUname() string {
return "" return ""
} }
func (x *MqDanmaku) GetContent() string { func (x *MqDanmaku) GetAvatar() string {
if x != nil {
return x.Avatar
}
return ""
}
func (x *MqDanmaku) GetMsg() string {
if x != nil {
return x.Msg
}
return ""
}
func (x *MqDanmaku) GetMsgId() string {
if x != nil { if x != nil {
return x.Content return x.MsgId
} }
return "" return ""
} }
func (x *MqDanmaku) GetSendTime() int64 { func (x *MqDanmaku) GetTimestamp() int64 {
if x != nil { if x != nil {
return x.SendTime return x.Timestamp
}
return 0
}
func (x *MqDanmaku) GetNobilityLevel() int64 {
if x != nil {
return x.NobilityLevel
}
return 0
}
func (x *MqDanmaku) GetFansMedalWearingStatus() bool {
if x != nil {
return x.FansMedalWearingStatus
}
return false
}
func (x *MqDanmaku) GetFansMedalName() string {
if x != nil {
return x.FansMedalName
}
return ""
}
func (x *MqDanmaku) GetFansMedalLevel() int64 {
if x != nil {
return x.FansMedalLevel
} }
return 0 return 0
} }
@ -295,11 +359,18 @@ type MqGift struct {
LiveRoomId int64 `protobuf:"varint,2,opt,name=liveRoomId,proto3" json:"liveRoomId,omitempty"` LiveRoomId int64 `protobuf:"varint,2,opt,name=liveRoomId,proto3" json:"liveRoomId,omitempty"`
Uid int64 `protobuf:"varint,3,opt,name=uid,proto3" json:"uid,omitempty"` Uid int64 `protobuf:"varint,3,opt,name=uid,proto3" json:"uid,omitempty"`
Uname string `protobuf:"bytes,4,opt,name=uname,proto3" json:"uname,omitempty"` Uname string `protobuf:"bytes,4,opt,name=uname,proto3" json:"uname,omitempty"`
GiftId int64 `protobuf:"varint,5,opt,name=giftId,proto3" json:"giftId,omitempty"` Avatar string `protobuf:"bytes,5,opt,name=avatar,proto3" json:"avatar,omitempty"` // 头像
Num int64 `protobuf:"varint,6,opt,name=num,proto3" json:"num,omitempty"` GiftId int64 `protobuf:"varint,6,opt,name=giftId,proto3" json:"giftId,omitempty"`
GiftName string `protobuf:"bytes,7,opt,name=giftName,proto3" json:"giftName,omitempty"` GiftName string `protobuf:"bytes,7,opt,name=giftName,proto3" json:"giftName,omitempty"`
Price int64 `protobuf:"varint,8,opt,name=price,proto3" json:"price,omitempty"` GiftNum int64 `protobuf:"varint,8,opt,name=giftNum,proto3" json:"giftNum,omitempty"`
IsPaid bool `protobuf:"varint,9,opt,name=isPaid,proto3" json:"isPaid,omitempty"` Price int64 `protobuf:"varint,9,opt,name=price,proto3" json:"price,omitempty"`
IsPaid bool `protobuf:"varint,10,opt,name=isPaid,proto3" json:"isPaid,omitempty"`
MsgId string `protobuf:"bytes,11,opt,name=msgId,proto3" json:"msgId,omitempty"` // 消息唯一ID
Timestamp int64 `protobuf:"varint,12,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // 收礼时间
NobilityLevel int64 `protobuf:"varint,13,opt,name=nobilityLevel,proto3" json:"nobilityLevel,omitempty"` // 贵族等级
FansMedalWearingStatus bool `protobuf:"varint,14,opt,name=fansMedalWearingStatus,proto3" json:"fansMedalWearingStatus,omitempty"` // 牌子佩戴状态
FansMedalName string `protobuf:"bytes,15,opt,name=fansMedalName,proto3" json:"fansMedalName,omitempty"` // 粉丝牌子名
FansMedalLevel int64 `protobuf:"varint,16,opt,name=fansMedalLevel,proto3" json:"fansMedalLevel,omitempty"` // 粉丝牌子等级
} }
func (x *MqGift) Reset() { func (x *MqGift) Reset() {
@ -362,16 +433,16 @@ func (x *MqGift) GetUname() string {
return "" return ""
} }
func (x *MqGift) GetGiftId() int64 { func (x *MqGift) GetAvatar() string {
if x != nil { if x != nil {
return x.GiftId return x.Avatar
} }
return 0 return ""
} }
func (x *MqGift) GetNum() int64 { func (x *MqGift) GetGiftId() int64 {
if x != nil { if x != nil {
return x.Num return x.GiftId
} }
return 0 return 0
} }
@ -383,6 +454,13 @@ func (x *MqGift) GetGiftName() string {
return "" return ""
} }
func (x *MqGift) GetGiftNum() int64 {
if x != nil {
return x.GiftNum
}
return 0
}
func (x *MqGift) GetPrice() int64 { func (x *MqGift) GetPrice() int64 {
if x != nil { if x != nil {
return x.Price return x.Price
@ -397,58 +475,137 @@ func (x *MqGift) GetIsPaid() bool {
return false return false
} }
func (x *MqGift) GetMsgId() string {
if x != nil {
return x.MsgId
}
return ""
}
func (x *MqGift) GetTimestamp() int64 {
if x != nil {
return x.Timestamp
}
return 0
}
func (x *MqGift) GetNobilityLevel() int64 {
if x != nil {
return x.NobilityLevel
}
return 0
}
func (x *MqGift) GetFansMedalWearingStatus() bool {
if x != nil {
return x.FansMedalWearingStatus
}
return false
}
func (x *MqGift) GetFansMedalName() string {
if x != nil {
return x.FansMedalName
}
return ""
}
func (x *MqGift) GetFansMedalLevel() int64 {
if x != nil {
return x.FansMedalLevel
}
return 0
}
var File_mq_proto protoreflect.FileDescriptor var File_mq_proto protoreflect.FileDescriptor
var file_mq_proto_rawDesc = []byte{ var file_mq_proto_rawDesc = []byte{
0x0a, 0x08, 0x6d, 0x71, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0xa4, 0x0a, 0x08, 0x6d, 0x71, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0x9b,
0x02, 0x0a, 0x0a, 0x4d, 0x71, 0x47, 0x75, 0x61, 0x72, 0x64, 0x42, 0x75, 0x79, 0x12, 0x1a, 0x0a, 0x03, 0x0a, 0x0d, 0x4d, 0x71, 0x4e, 0x6f, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x42, 0x75, 0x79,
0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01,
0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x1e, 0x0a, 0x0a, 0x6c, 0x69, 0x76, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x1e, 0x0a, 0x0a,
0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x6c, 0x6c, 0x69, 0x76, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03,
0x69, 0x76, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x52, 0x0a, 0x6c, 0x69, 0x76, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03,
0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x14,
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x75, 0x6e, 0x61, 0x6d, 0x0a, 0x05, 0x75, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x75,
0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x67, 0x75, 0x61, 0x72, 0x64, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x05,
0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x67, 0x75, 0x61, 0x72, 0x64, 0x4c, 0x65, 0x76, 0x65, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x14, 0x0a, 0x05,
0x6c, 0x12, 0x10, 0x0a, 0x03, 0x6e, 0x75, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x73, 0x67,
0x6e, 0x75, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x6e, 0x6f, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x4c, 0x65,
0x28, 0x03, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x69, 0x66, 0x76, 0x65, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6e, 0x6f, 0x62, 0x69, 0x6c,
0x74, 0x49, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x67, 0x69, 0x66, 0x74, 0x49, 0x69, 0x74, 0x79, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63,
0x64, 0x12, 0x1a, 0x0a, 0x08, 0x67, 0x69, 0x66, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x12, 0x1c,
0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x69, 0x66, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28,
0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x03, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07,
0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x65,
0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x65, 0x6e, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x16, 0x66, 0x61, 0x6e, 0x73, 0x4d, 0x65,
0x64, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xa5, 0x01, 0x0a, 0x09, 0x4d, 0x71, 0x44, 0x61, 0x6e, 0x6d, 0x64, 0x61, 0x6c, 0x57, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
0x61, 0x6b, 0x75, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x66, 0x61, 0x6e, 0x73, 0x4d, 0x65, 0x64, 0x61,
0x6c, 0x57, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x24,
0x0a, 0x0d, 0x66, 0x61, 0x6e, 0x73, 0x4d, 0x65, 0x64, 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x18,
0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x66, 0x61, 0x6e, 0x73, 0x4d, 0x65, 0x64, 0x61, 0x6c,
0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x66, 0x61, 0x6e, 0x73, 0x4d, 0x65, 0x64, 0x61,
0x6c, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x66, 0x61,
0x6e, 0x73, 0x4d, 0x65, 0x64, 0x61, 0x6c, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0xf9, 0x02, 0x0a,
0x09, 0x4d, 0x71, 0x44, 0x61, 0x6e, 0x6d, 0x61, 0x6b, 0x75, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c,
0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c,
0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x1e, 0x0a, 0x0a, 0x6c, 0x69, 0x76, 0x65, 0x52, 0x6f,
0x6f, 0x6d, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x6c, 0x69, 0x76, 0x65,
0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20,
0x01, 0x28, 0x03, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x6e, 0x61, 0x6d,
0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x75, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16,
0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x06, 0x20,
0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x73, 0x67, 0x49,
0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x1c,
0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28,
0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x24, 0x0a, 0x0d,
0x6e, 0x6f, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x09, 0x20,
0x01, 0x28, 0x03, 0x52, 0x0d, 0x6e, 0x6f, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x4c, 0x65, 0x76,
0x65, 0x6c, 0x12, 0x36, 0x0a, 0x16, 0x66, 0x61, 0x6e, 0x73, 0x4d, 0x65, 0x64, 0x61, 0x6c, 0x57,
0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0a, 0x20, 0x01,
0x28, 0x08, 0x52, 0x16, 0x66, 0x61, 0x6e, 0x73, 0x4d, 0x65, 0x64, 0x61, 0x6c, 0x57, 0x65, 0x61,
0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x66, 0x61,
0x6e, 0x73, 0x4d, 0x65, 0x64, 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0d, 0x66, 0x61, 0x6e, 0x73, 0x4d, 0x65, 0x64, 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65,
0x12, 0x26, 0x0a, 0x0e, 0x66, 0x61, 0x6e, 0x73, 0x4d, 0x65, 0x64, 0x61, 0x6c, 0x4c, 0x65, 0x76,
0x65, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x66, 0x61, 0x6e, 0x73, 0x4d, 0x65,
0x64, 0x61, 0x6c, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0xe0, 0x03, 0x0a, 0x06, 0x4d, 0x71, 0x47,
0x69, 0x66, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12,
0x1e, 0x0a, 0x0a, 0x6c, 0x69, 0x76, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x18, 0x02, 0x20, 0x1e, 0x0a, 0x0a, 0x6c, 0x69, 0x76, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x18, 0x02, 0x20,
0x01, 0x28, 0x03, 0x52, 0x0a, 0x6c, 0x69, 0x76, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x12, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x6c, 0x69, 0x76, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x12,
0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x75, 0x69, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x75, 0x69,
0x64, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
0x52, 0x05, 0x75, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x52, 0x05, 0x75, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61,
0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12,
0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x16, 0x0a, 0x06, 0x67, 0x69, 0x66, 0x74, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52,
0x01, 0x28, 0x03, 0x52, 0x08, 0x73, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xe0, 0x01, 0x06, 0x67, 0x69, 0x66, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x67, 0x69, 0x66, 0x74, 0x4e,
0x0a, 0x06, 0x4d, 0x71, 0x47, 0x69, 0x66, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x69, 0x66, 0x74, 0x4e,
0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x67, 0x69, 0x66, 0x74, 0x4e, 0x75, 0x6d, 0x18, 0x08,
0x66, 0x6f, 0x72, 0x6d, 0x12, 0x1e, 0x0a, 0x0a, 0x6c, 0x69, 0x76, 0x65, 0x52, 0x6f, 0x6f, 0x6d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x67, 0x69, 0x66, 0x74, 0x4e, 0x75, 0x6d, 0x12, 0x14, 0x0a,
0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x6c, 0x69, 0x76, 0x65, 0x52, 0x6f, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x70, 0x72,
0x6f, 0x6d, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x69, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x50, 0x61, 0x69, 0x64, 0x18, 0x0a, 0x20,
0x03, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x50, 0x61, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6d,
0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x75, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x67, 0x49, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x73, 0x67, 0x49,
0x67, 0x69, 0x66, 0x74, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x67, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0c,
0x66, 0x74, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6e, 0x75, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12,
0x03, 0x52, 0x03, 0x6e, 0x75, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x67, 0x69, 0x66, 0x74, 0x4e, 0x61, 0x24, 0x0a, 0x0d, 0x6e, 0x6f, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x4c, 0x65, 0x76, 0x65, 0x6c,
0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x69, 0x66, 0x74, 0x4e, 0x61, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6e, 0x6f, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79,
0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x36, 0x0a, 0x16, 0x66, 0x61, 0x6e, 0x73, 0x4d, 0x65, 0x64,
0x03, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x50, 0x61, 0x61, 0x6c, 0x57, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18,
0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x50, 0x61, 0x69, 0x64, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x66, 0x61, 0x6e, 0x73, 0x4d, 0x65, 0x64, 0x61, 0x6c,
0x2a, 0x39, 0x0a, 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x0c, 0x0a, 0x08, 0x57, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x24, 0x0a,
0x62, 0x69, 0x6c, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x68, 0x75, 0x0d, 0x66, 0x61, 0x6e, 0x73, 0x4d, 0x65, 0x64, 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x0f,
0x79, 0x61, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x64, 0x6f, 0x75, 0x79, 0x75, 0x10, 0x02, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x66, 0x61, 0x6e, 0x73, 0x4d, 0x65, 0x64, 0x61, 0x6c, 0x4e,
0x0a, 0x0a, 0x06, 0x64, 0x6f, 0x75, 0x79, 0x69, 0x6e, 0x10, 0x03, 0x42, 0x07, 0x5a, 0x05, 0x2f, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x66, 0x61, 0x6e, 0x73, 0x4d, 0x65, 0x64, 0x61, 0x6c,
0x70, 0x62, 0x4d, 0x71, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x10, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x66, 0x61, 0x6e,
0x73, 0x4d, 0x65, 0x64, 0x61, 0x6c, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x2a, 0x39, 0x0a, 0x08, 0x50,
0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x0c, 0x0a, 0x08, 0x62, 0x69, 0x6c, 0x69, 0x62,
0x69, 0x6c, 0x69, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x68, 0x75, 0x79, 0x61, 0x10, 0x01, 0x12,
0x09, 0x0a, 0x05, 0x64, 0x6f, 0x75, 0x79, 0x75, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x64, 0x6f,
0x75, 0x79, 0x69, 0x6e, 0x10, 0x03, 0x42, 0x07, 0x5a, 0x05, 0x2f, 0x70, 0x62, 0x4d, 0x71, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@ -467,7 +624,7 @@ var file_mq_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_mq_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_mq_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_mq_proto_goTypes = []interface{}{ var file_mq_proto_goTypes = []interface{}{
(Platform)(0), // 0: pb.Platform (Platform)(0), // 0: pb.Platform
(*MqGuardBuy)(nil), // 1: pb.MqGuardBuy (*MqNobilityBuy)(nil), // 1: pb.MqNobilityBuy
(*MqDanmaku)(nil), // 2: pb.MqDanmaku (*MqDanmaku)(nil), // 2: pb.MqDanmaku
(*MqGift)(nil), // 3: pb.MqGift (*MqGift)(nil), // 3: pb.MqGift
} }
@ -486,7 +643,7 @@ func file_mq_proto_init() {
} }
if !protoimpl.UnsafeEnabled { if !protoimpl.UnsafeEnabled {
file_mq_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { file_mq_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MqGuardBuy); i { switch v := v.(*MqNobilityBuy); i {
case 0: case 0:
return &v.state return &v.state
case 1: case 1:

@ -11,27 +11,36 @@ enum Platform {
douyin = 3; // douyin = 3; //
} }
message MqGuardBuy { message MqNobilityBuy {
string platform = 1; string platform = 1; //
int64 liveRoomId = 2; int64 liveRoomId = 2; // ID
int64 uid = 3; int64 uid = 3; // ID
string uname = 4; string uname = 4; //
int32 guardLevel = 5; string avatar = 5; //
int32 num = 6; string msgId = 6; // ID
int64 price = 7; int64 nobilityLevel = 7; //
int64 giftId = 8; int64 price = 8; // price
string giftName = 9; int64 startTime = 9; //
int64 startTime = 10; int64 endTime = 10; //
int64 endTime = 11;
bool fansMedalWearingStatus = 11; //
string fansMedalName = 12; //
int64 fansMedalLevel = 13; //
} }
message MqDanmaku { message MqDanmaku {
string platform = 1; string platform = 1; //
int64 liveRoomId = 2; int64 liveRoomId = 2; // ID
int64 uid = 3; int64 uid = 3; // ID
string uname = 4; string uname = 4; //
string content = 5; string avatar = 5; //
int64 sendTime = 6; string msg = 6; //
string msgId = 7; // ID
int64 timestamp = 8; //
int64 nobilityLevel = 9; //
bool fansMedalWearingStatus = 10; //
string fansMedalName = 11; //
int64 fansMedalLevel = 12; //
} }
message MqGift { message MqGift {
@ -39,9 +48,18 @@ message MqGift {
int64 liveRoomId = 2; int64 liveRoomId = 2;
int64 uid = 3; int64 uid = 3;
string uname = 4; string uname = 4;
int64 giftId = 5; string avatar = 5; //
int64 num = 6;
int64 giftId = 6;
string giftName = 7; string giftName = 7;
int64 price = 8; int64 giftNum = 8;
bool isPaid = 9; int64 price = 9;
bool isPaid = 10;
string msgId = 11; // ID
int64 timestamp = 12; //
int64 nobilityLevel = 13; //
bool fansMedalWearingStatus = 14; //
string fansMedalName = 15; //
int64 fansMedalLevel = 16; //
} }

@ -0,0 +1,28 @@
package timex
import (
"github.com/jinzhu/now"
"time"
)
// DayExpire 日期是否过期
// 使用 BeginningOfDay 判断
func DayExpire(nowTime time.Time, src time.Time, forever bool) bool {
if forever {
return false
}
today := now.With(nowTime).BeginningOfDay()
return !today.Before(now.With(src).BeginningOfDay())
}
// DayRemain 剩余天数(包括今天)
func DayRemain(nowTime time.Time, src time.Time, forever bool) int32 {
if forever {
return -1
}
resp := int32(src.YearDay() - nowTime.YearDay())
if resp < 0 {
resp = 0
}
return resp
}

@ -0,0 +1,22 @@
package timex
import "time"
const (
seconds = 1e11
milliseconds = 1e14
microseconds = 1e17
)
func TimestampToTime(ts int64) time.Time {
if ts < seconds {
return time.Unix(ts, 0)
}
if ts < milliseconds {
return time.Unix(ts/1000, (ts%1000)*1e6)
}
if ts < microseconds {
return time.Unix(ts/1e6, (ts%1e6)*1000)
}
return time.Unix(0, ts)
}
Loading…
Cancel
Save