var apilog = c.C.Log.Base(`api`)
var api_limit = limit.New(2, "1s", "30s") //频率限制2次/s,最大等待时间30s
-var biliApi = cmp.Get(id, func(ba biliApiInter) biliApiInter {
+var biliApi = cmp.Get(id, func(ba BiliApiInter) BiliApiInter {
ba.SetLocation(c.C.SerLocation)
ba.SetProxy(c.C.Proxy)
ba.SetReqPool(c.C.ReqPool)
// 牌子字段
// 获取牌子信息
-func GetListInRoom(RoomID, TargetID int) (array []struct {
- TargetID int
- IsLighted int
- MedalID int
- RoomID int
-}) {
- apilog := apilog.Base_add(`获取牌子`)
- //验证cookie
- if missKey := CookieCheck([]string{
- `bili_jct`,
- `DedeUserID`,
- `LIVE_BUVID`,
- }); len(missKey) != 0 {
- apilog.L(`T: `, `Cookie无Key:`, missKey)
- return
- }
+// func GetListInRoom(RoomID, TargetID int) (array []struct {
+// Uid int
+// TodayFeed int
+// TargetID int
+// IsLighted int
+// MedalID int
+// RoomID int
+// }) {
+// apilog := apilog.Base_add(`获取牌子`)
+// //验证cookie
+// if missKey := CookieCheck([]string{
+// `bili_jct`,
+// `DedeUserID`,
+// `LIVE_BUVID`,
+// }); len(missKey) != 0 {
+// apilog.L(`T: `, `Cookie无Key:`, missKey)
+// return
+// }
- //getHotRank
- if err, res := biliApi.GetFansMedal(RoomID, TargetID); err != nil {
- apilog.L(`E: `, err)
- } else {
- return res
- }
+// //getHotRank
+// if err, res := biliApi.GetFansMedal(RoomID, TargetID); err != nil {
+// apilog.L(`E: `, err)
+// } else {
+// return res
+// }
- return
+// return
+// }
+
+func GetBiliApi() BiliApiInter {
+ return biliApi
}
// 获取当前佩戴的牌子
var medal_id int //将要使用的牌子id
//检查是否有此直播间的牌子
{
- medal_list := GetListInRoom(t.Roomid, t.UpUid)
- for _, v := range medal_list {
- if v.TargetID != t.UpUid {
- continue
+ if err, medal_list := biliApi.GetFansMedal(t.Roomid, t.UpUid); err != nil {
+ apilog.L(`E: `, err)
+ } else {
+ for _, v := range medal_list {
+ if v.TargetID != t.UpUid {
+ continue
+ }
+ medal_id = v.MedalID
}
- medal_id = v.MedalID
- }
- if medal_id == 0 { //无牌
- apilog.L(`I: `, `无主播粉丝牌`)
- if t.Wearing_FansMedal == 0 { //当前没牌
- return
+ if medal_id == 0 { //无牌
+ apilog.L(`I: `, `无主播粉丝牌`)
+ if t.Wearing_FansMedal == 0 { //当前没牌
+ return
+ }
}
}
}
return
}
-func GetHistory(Roomid_int int) (j []string) {
- apilog := apilog.Base_add(`GetHistory`)
+// func GetHistory(Roomid_int int) (j []string) {
+// apilog := apilog.Base_add(`GetHistory`)
- if e, res := biliApi.GetHisDanmu(Roomid_int); e != nil {
- apilog.L(`E: `, e)
- return
- } else {
- return res
- }
-}
+// if e, res := biliApi.GetHisDanmu(Roomid_int); e != nil {
+// apilog.L(`E: `, e)
+// return
+// } else {
+// return res
+// }
+// }
func (t *GetFunc) SearchUP(s string) (list []struct {
Roomid int
reqf "github.com/qydysky/part/reqf"
)
-type biliApiInter interface {
+type BiliApiInter interface {
SetReqPool(pool *pool.Buf[reqf.Req])
SetProxy(proxy string)
SetLocation(secOfTimeZone int) // east positive
GetCookies() (cookies []*http.Cookie)
GetCookie(name string) (error, string)
+ LikeReport(hitCount, uid, roomid, upUid int) (err error)
LoginQrCode() (err error, imgUrl string, QrcodeKey string)
LoginQrPoll(QrcodeKey string) (err error, code int)
GetOtherCookies() (err error)
TargetID int
})
GetFansMedal(RoomID, TargetID int) (err error, res []struct {
- TargetID int
- IsLighted int
- MedalID int
- RoomID int
+ TodayFeed int
+ TargetID int
+ IsLighted int
+ MedalID int
+ RoomID int
+ LivingStatus int
})
SetFansMedal(medalId int) (err error)
GetWebGetSignInfo() (err error, Status int)
}
// 保持所有牌子点亮
-func KeepMedalLight(common *c.Common) {
+func KeepMedalLight(ctx context.Context, common *c.Common) {
if v, _ := common.K_v.LoadV(`保持牌子亮着`).(bool); !v {
return
}
- flog := flog.Base_add(`保持亮牌`)
-
- array, _ := common.K_v.LoadV(`进房弹幕_内容`).([]any)
-
- flog.L(`T: `, `开始`)
- defer flog.L(`I: `, `完成`)
- var lightedRoom []int
- for _, v := range F.GetListInRoom(0, 0) {
- if v.IsLighted == 1 {
- lightedRoom = append(lightedRoom, v.RoomID)
- }
+ v, _ := common.K_v.LoadV(`保持牌子亮着_指定时间`).(string)
+ if v == "" {
+ v = "00:00:00"
}
- if _, e := keepMedalLight.KeepMedalLight.Run(context.Background(), keepMedalLight.Func{
- LightedRoomID: lightedRoom,
- SendDanmu: send.Danmu_s,
- GetHistoryDanmu: F.GetHistory,
- PreferDanmu: array,
- }); e != nil {
+
+ flog := flog.Base_add(`保持亮牌`)
+ if tt, e := time.Parse(time.TimeOnly, v); e != nil {
flog.L(`E: `, e)
+ } else {
+ flog.L(`I: `, "将在", v, "启动")
+ sec := tt.Hour()*3600 + tt.Minute()*60 + tt.Second()
+ go func() {
+ ctx, done := pctx.WaitCtx(ctx)
+ defer done()
+
+ h, m, s := time.Now().Clock()
+ now := h*3600 + m*60 + s
+
+ if sec > now {
+ select {
+ case <-time.After(time.Second * time.Duration(sec-now)):
+ case <-ctx.Done():
+ return
+ }
+ } else {
+ select {
+ case <-time.After(time.Hour*24 + time.Second*time.Duration(sec-now)):
+ case <-ctx.Done():
+ return
+ }
+ }
+
+ for {
+ if _, e := keepMedalLight.Main.Run(ctx, keepMedalLight.Func{
+ Uid: common.Uid,
+ Logg: flog,
+ BiliApi: F.GetBiliApi(),
+ SendDanmu: send.Danmu_s,
+ PreferDanmu: common.K_v.LoadV(`进房弹幕_内容`).([]any),
+ }); e != nil {
+ flog.L(`E: `, e)
+ return
+ }
+ select {
+ case <-time.After(time.Hour * 24):
+ case <-ctx.Done():
+ return
+ }
+ }
+ }()
}
}
import (
"context"
+ "errors"
"sync/atomic"
"time"
+ "github.com/qydysky/bili_danmu/F"
p "github.com/qydysky/part"
+
comp "github.com/qydysky/part/component"
+ reqf "github.com/qydysky/part/reqf"
+
+ log "github.com/qydysky/part/log"
)
var (
- KeepMedalLight = comp.NewComp(keepMedalLight)
- skip atomic.Bool
+ Main = comp.NewComp(main)
+ rand = p.Rand()
+ roomI = make(map[int]*room)
+ skip atomic.Bool
+ ErrNotFoundRoom = errors.New(`ErrNotFoundRoom`)
+ ErrNotLight = errors.New(`ErrNotLight`)
)
type Func struct {
- LightedRoomID []int // 熄灭的徽章只能通过送礼物点亮
- SendDanmu func(danmu string, RoomID int) error
- GetHistoryDanmu func(RoomID int) []string
- PreferDanmu []any
+ Uid int
+ Logg *log.Log_interface
+ BiliApi F.BiliApiInter
+ SendDanmu func(danmu string, RoomID int) error
+ PreferDanmu []any
}
-func keepMedalLight(ctx context.Context, ptr Func) (ret any, err error) {
+type room struct {
+ medalID int
+ targetID int
+ danmu int
+ like int
+}
+
+func main(ctx context.Context, ptr Func) (ret any, err error) {
if !skip.CompareAndSwap(false, true) {
return
}
- defer skip.Store(false)
- for i := 0; i < len(ptr.LightedRoomID); i++ {
- time.Sleep(time.Second * 5)
+ ptr.Logg.L(`T: `, `开始`)
+ t := time.NewTicker(time.Second * 5)
- if len(ptr.PreferDanmu) > 0 {
- rand := p.Rand().MixRandom(0, int64(len(ptr.PreferDanmu)-1))
- if s, ok := ptr.PreferDanmu[rand].(string); ok {
- if e := ptr.SendDanmu(s, ptr.LightedRoomID[i]); e == nil {
- continue
- } else {
- err = e
+ defer func() {
+ t.Stop()
+ ptr.Logg.L(`I: `, `完成`)
+ skip.Store(false)
+ }()
+
+ if e, list := ptr.BiliApi.GetFansMedal(0, 0); e != nil {
+ return nil, e
+ } else {
+ for _, v := range list {
+ // 熄灭的徽章只能通过送礼物点亮
+ if v.TodayFeed > 0 {
+ delete(roomI, v.RoomID)
+ continue
+ } else if v.IsLighted == 1 {
+ roomI[v.RoomID] = &room{
+ targetID: v.TargetID,
+ medalID: v.MedalID,
}
}
}
+ }
- if e := ptr.SendDanmu(`点赞`, ptr.LightedRoomID[i]); e == nil {
- continue
- } else {
- err = e
- }
+ ptr.Logg.L(`I: `, "等待保持点亮数量", len(roomI))
+
+ for len(roomI) != 0 && err == nil {
+ // deal roomI
+ for roomid, v := range roomI {
- his := ptr.GetHistoryDanmu(ptr.LightedRoomID[i])
+ select {
+ case <-ctx.Done():
+ return
+ case <-t.C:
+ }
- if len(his) > 0 {
- if e := ptr.SendDanmu(his[0], ptr.LightedRoomID[i]); e == nil {
+ if e, tmp := ptr.BiliApi.GetFansMedal(roomid, v.targetID); e != nil && !reqf.IsTimeout(e) {
+ err = e
+ } else if len(tmp) == 0 {
+ err = ErrNotFoundRoom
+ } else if tmp[0].TodayFeed > 0 {
+ delete(roomI, roomid)
+ ptr.Logg.L(`I: `, roomid, "已获得亲密度", tmp[0].TodayFeed, "剩余", len(roomI))
continue
+ } else if tmp[0].LivingStatus == 1 {
+ if e := ptr.BiliApi.LikeReport(15, ptr.Uid, roomid, v.targetID); e == nil {
+ v.like += 15
+ } else if !reqf.IsTimeout(e) {
+ err = e
+ }
} else {
- err = e
+ if len(ptr.PreferDanmu) > 0 {
+ if s, ok := ptr.PreferDanmu[rand.MixRandom(0, int64(len(ptr.PreferDanmu)-1))].(string); ok {
+ if e := ptr.SendDanmu(s, roomid); e == nil {
+ v.danmu += 1
+ } else if !reqf.IsTimeout(e) {
+ err = e
+ }
+ }
+ } else if e := ptr.SendDanmu(`点赞`, roomid); e == nil {
+ v.danmu += 1
+ } else if !reqf.IsTimeout(e) {
+ err = e
+ }
+ }
+
+ if v.danmu < 10 && v.like < 50 {
+ // 发送弹幕:每日首次发送弹幕达10条可获得70亲密度
+ // 给主播点赞:每日首次点满50个赞可获得50亲密度
+ continue
+ } else if v.danmu > 20 || v.like > 70 {
+ delete(roomI, roomid)
+ ptr.Logg.L(`I: `, roomid, "未获得亲密度")
+ break
}
}
}
F.Dosign()
// 附加功能 savetojson
reply.SaveToJson.Init()
+ // 附加功能 保持牌子点亮
+ reply.KeepMedalLight(mainCtx, c.C)
// 指定房间录制区间
if _, err := recStartEnd.InitF.Run(mainCtx, c.C); err != nil {
danmulog.Base("功能", "指定房间录制区间").L(`E: `, err)
F.Get(c.C).Silver_2_coin()
//附加功能 每日发送弹幕
reply.Entry_danmu(c.C)
- //附加功能 保持牌子点亮
- reply.KeepMedalLight(c.C)
//附加功能 自动发送即将过期礼物
reply.AutoSend_silver_gift(c.C)
}()
}
func entryRoom(mainCtx context.Context, danmulog *part.Log_interface, common *c.Common) (exitSign bool) {
- //附加功能 保持牌子点亮
- // go reply.KeepMedalLight(common)
//附加功能 自动发送即将过期礼物
go reply.AutoSend_silver_gift(common)
//获取热门榜
"弹幕_识别表情代码": true,
"发送还有几天过期的礼物": 3,
"保持牌子亮着": true,
+ "保持牌子亮着_指定时间": "00:00:00",
"弹幕输出到日志": true,
"保存弹幕至db": {
"dbname": "",