]> 127.0.0.1 Git - bili_danmu/.git/commitdiff
Improve 保持牌子点亮策略调整
authorqydysky <qydysky@foxmail.com>
Thu, 25 Jul 2024 19:11:30 +0000 (03:11 +0800)
committerqydysky <qydysky@foxmail.com>
Thu, 25 Jul 2024 19:11:30 +0000 (03:11 +0800)
F/api.go
F/biliApiInterface.go
Reply/F.go
Reply/F/keepMedalLight/keepMedalLight.go
bili_danmu.go
demo/config/config_K_v.json

index 687816e32bff81e9a7acc286bde673c67e40f033..d78c5558a512ef4f0ff9a437a760468d084c20c3 100644 (file)
--- a/F/api.go
+++ b/F/api.go
@@ -37,7 +37,7 @@ const id = "github.com/qydysky/bili_danmu/F.biliApi"
 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)
@@ -1085,31 +1085,37 @@ func Get_cookie_by_msg() {
 
 // 牌子字段
 // 获取牌子信息
-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
 }
 
 // 获取当前佩戴的牌子
@@ -1176,17 +1182,20 @@ func (t *GetFunc) CheckSwitch_FansMedal() (missKey []string) {
        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
+                               }
                        }
                }
        }
@@ -1531,16 +1540,16 @@ func Feed_list() (Uplist []struct {
        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
index 070e4fb0f72bce0b7a42e3a6734bdd6a0f332c6d..eed35c5895fd4ed9f10d80e0d21a0c609dab23be 100644 (file)
@@ -8,7 +8,7 @@ import (
        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
@@ -16,6 +16,7 @@ type biliApiInter interface {
        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)
@@ -93,10 +94,12 @@ type biliApiInter interface {
                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)
index e80f2240b32b6991c54df913ba02bfcfff12a52e..76f1c1e5cf1064ed3917f5e3eabaa37b43d72f0a 100644 (file)
@@ -993,30 +993,61 @@ func Entry_danmu(common *c.Common) {
 }
 
 // 保持所有牌子点亮
-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
+                               }
+                       }
+               }()
        }
 }
 
index 1ea89a09d3ee18162cb7f8c75577fbba0d2eddf0..a82f336f0def0b12a81e45a7ae975a099c438e04 100644 (file)
@@ -2,58 +2,124 @@ package keepMedalLight
 
 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
                        }
                }
        }
index 727ae281418e2080f4e22905b9bf3d3294210999..efbbd95b14f57adfa6af4cba635c07cd1669d7a2 100644 (file)
@@ -98,6 +98,8 @@ func Start() {
                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)
@@ -186,8 +188,6 @@ func Start() {
                                                F.Get(c.C).Silver_2_coin()
                                                //附加功能 每日发送弹幕
                                                reply.Entry_danmu(c.C)
-                                               //附加功能 保持牌子点亮
-                                               reply.KeepMedalLight(c.C)
                                                //附加功能 自动发送即将过期礼物
                                                reply.AutoSend_silver_gift(c.C)
                                        }()
@@ -248,8 +248,6 @@ func Start() {
 }
 
 func entryRoom(mainCtx context.Context, danmulog *part.Log_interface, common *c.Common) (exitSign bool) {
-       //附加功能 保持牌子点亮
-       // go reply.KeepMedalLight(common)
        //附加功能 自动发送即将过期礼物
        go reply.AutoSend_silver_gift(common)
        //获取热门榜
index 0d5f07bd58d678fbe6f94f209cfd8080612e07c7..e46f2d022d0b8efa7b1a27d1044548c62087255f 100644 (file)
@@ -40,6 +40,7 @@
     "弹幕_识别表情代码": true,
     "发送还有几天过期的礼物": 3,
     "保持牌子亮着": true,
+    "保持牌子亮着_指定时间": "00:00:00",
     "弹幕输出到日志": true,
     "保存弹幕至db": {
         "dbname": "",