From bcd87478569c1ecf63b2e934eb2f64f7cf7ade30 Mon Sep 17 00:00:00 2001 From: qydysky Date: Fri, 26 Jul 2024 03:11:30 +0800 Subject: [PATCH] =?utf8?q?Improve=20=E4=BF=9D=E6=8C=81=E7=89=8C=E5=AD=90?= =?utf8?q?=E7=82=B9=E4=BA=AE=E7=AD=96=E7=95=A5=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- F/api.go | 95 +++++++++--------- F/biliApiInterface.go | 13 ++- Reply/F.go | 67 +++++++++---- Reply/F/keepMedalLight/keepMedalLight.go | 118 ++++++++++++++++++----- bili_danmu.go | 6 +- demo/config/config_K_v.json | 1 + 6 files changed, 204 insertions(+), 96 deletions(-) diff --git a/F/api.go b/F/api.go index 687816e..d78c555 100644 --- 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 diff --git a/F/biliApiInterface.go b/F/biliApiInterface.go index 070e4fb..eed35c5 100644 --- a/F/biliApiInterface.go +++ b/F/biliApiInterface.go @@ -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) diff --git a/Reply/F.go b/Reply/F.go index e80f224..76f1c1e 100644 --- a/Reply/F.go +++ b/Reply/F.go @@ -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 + } + } + }() } } diff --git a/Reply/F/keepMedalLight/keepMedalLight.go b/Reply/F/keepMedalLight/keepMedalLight.go index 1ea89a0..a82f336 100644 --- a/Reply/F/keepMedalLight/keepMedalLight.go +++ b/Reply/F/keepMedalLight/keepMedalLight.go @@ -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 } } } diff --git a/bili_danmu.go b/bili_danmu.go index 727ae28..efbbd95 100644 --- a/bili_danmu.go +++ b/bili_danmu.go @@ -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) //获取热门榜 diff --git a/demo/config/config_K_v.json b/demo/config/config_K_v.json index 0d5f07b..e46f2d0 100644 --- a/demo/config/config_K_v.json +++ b/demo/config/config_K_v.json @@ -40,6 +40,7 @@ "弹幕_识别表情代码": true, "发送还有几天过期的礼物": 3, "保持牌子亮着": true, + "保持牌子亮着_指定时间": "00:00:00", "弹幕输出到日志": true, "保存弹幕至db": { "dbname": "", -- 2.39.2