From 92a242cca30fb0222eca924c8278cba3874d064e Mon Sep 17 00:00:00 2001 From: qydysky <32743305+qydysky@users.noreply.github.com> Date: Fri, 20 Jan 2023 07:21:48 +0800 Subject: [PATCH] =?utf8?q?Add=20Featrue=20=E5=9C=A8=E7=BA=BF=E4=BA=BA?= =?utf8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- CV/Var.go | 1 + F/api.go | 70 ++++++++++++++++++++++++++++-- Json/getOnlineGoldRank.go | 39 +++++++++++++++++ Reply/Reply.go | 89 ++++++++++++++++++++++----------------- bili_danmu.go | 45 ++++++++++++-------- cmd/cmd.go | 2 +- 6 files changed, 187 insertions(+), 59 deletions(-) create mode 100644 Json/getOnlineGoldRank.go diff --git a/CV/Var.go b/CV/Var.go index 0036b21..3c6649f 100644 --- a/CV/Var.go +++ b/CV/Var.go @@ -31,6 +31,7 @@ type Common struct { Rev float64 //营收 Renqi int //人气 Watched int //观看人数 + OnlineNum int //在线人数 GuardNum int //舰长数 ParentAreaID int //父分区 AreaID int //子分区 diff --git a/F/api.go b/F/api.go index 4815792..5afaad0 100644 --- a/F/api.go +++ b/F/api.go @@ -47,7 +47,7 @@ func (c *GetFunc) Get(key string) { } //超额请求阻塞,超时将取消 var ( - api_can_get = map[string][]func() []string{ + api_can_get = map[string][]func() (missKey []string){ `Cookie`: { //Cookie c.Get_cookie, }, @@ -136,8 +136,12 @@ func (c *GetFunc) Get(key string) { `CheckSwitch_FansMedal`: { //切换粉丝牌 c.CheckSwitch_FansMedal, }, + `getOnlineGoldRank`: { //切换粉丝牌 + c.getOnlineGoldRank, + }, } - check = map[string]func() bool{ + // 验证是否有效 + check = map[string]func() (valid bool){ `Uid`: func() bool { //用戶uid return c.Uid != 0 }, @@ -209,7 +213,7 @@ func (c *GetFunc) Get(key string) { if fList, ok := api_can_get[key]; ok { for _, fItem := range fList { - apilog.L(`T: `, `Get`, key) + apilog.Log_show_control(false).L(`T: `, `Get`, key) missKey := fItem() if len(missKey) > 0 { apilog.L(`T: `, `missKey when get`, key, missKey) @@ -2411,6 +2415,66 @@ func RoomEntryAction(roomId int) { } } +// 获取在线人数 +func (c *GetFunc) getOnlineGoldRank() (misskey []string) { + apilog := apilog.Base_add(`获取在线人数`) + if c.UpUid == 0 { + misskey = append(misskey, `UpUid`) + return + } + if c.Roomid == 0 { + misskey = append(misskey, `Roomid`) + return + } + + if api_limit.TO() { + apilog.L(`E: `, `超时!`) + return + } //超额请求阻塞,超时将取消 + + reqi := c.ReqPool.Get() + defer c.ReqPool.Put(reqi) + req := reqi.Item.(*reqf.Req) + + if err := req.Reqf(reqf.Rval{ + Url: fmt.Sprintf("https://api.live.bilibili.com/xlive/general-interface/v1/rank/getOnlineGoldRank?ruid=%d&roomId=%d&page=1&pageSize=10", c.UpUid, c.Roomid), + Header: map[string]string{ + `Host`: `api.live.bilibili.com`, + `User-Agent`: `Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:103.0) Gecko/20100101 Firefox/103.0`, + `Accept`: `application/json, text/plain, */*`, + `Accept-Language`: `zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2`, + `Accept-Encoding`: `gzip, deflate, br`, + `Origin`: `https://live.bilibili.com`, + `Connection`: `keep-alive`, + `Pragma`: `no-cache`, + `Cache-Control`: `no-cache`, + `Referer`: fmt.Sprintf("https://live.bilibili.com/%d", c.Roomid), + }, + Proxy: c.Proxy, + Timeout: 3 * 1000, + Retry: 2, + }); err != nil { + apilog.L(`E: `, err) + return + } + + var res J.GetOnlineGoldRank + + if e := json.Unmarshal(req.Respon, &res); e != nil { + apilog.L(`E: `, e) + return + } + + if res.Code != 0 { + apilog.L(`E: `, res.Message) + return + } + + c.OnlineNum = res.Data.OnlineNum + apilog.Log_show_control(false).L(`I: `, `在线人数:`, c.OnlineNum) + return +} + func Feed_list() (Uplist []J.FollowingDataList) { apilog := apilog.Base_add(`正在直播主播`).L(`T: `, `获取中`) defer apilog.L(`T: `, `完成`) diff --git a/Json/getOnlineGoldRank.go b/Json/getOnlineGoldRank.go new file mode 100644 index 0000000..9447fb2 --- /dev/null +++ b/Json/getOnlineGoldRank.go @@ -0,0 +1,39 @@ +package part + +type GetOnlineGoldRank struct { + Code int `json:"code"` + Message string `json:"message"` + TTL int `json:"ttl"` + Data struct { + OnlineNum int `json:"onlineNum"` + OnlineRankItem []struct { + UserRank int `json:"userRank"` + UID int `json:"uid"` + Name string `json:"name"` + Face string `json:"face"` + Score int `json:"score"` + MedalInfo struct { + GuardLevel int `json:"guardLevel"` + MedalColorStart int `json:"medalColorStart"` + MedalColorEnd int `json:"medalColorEnd"` + MedalColorBorder int `json:"medalColorBorder"` + MedalName string `json:"medalName"` + Level int `json:"level"` + TargetID int `json:"targetId"` + IsLight int `json:"isLight"` + } `json:"medalInfo"` + GuardLevel int `json:"guard_level"` + } `json:"OnlineRankItem"` + OwnInfo struct { + UID int `json:"uid"` + Name string `json:"name"` + Face string `json:"face"` + Rank int `json:"rank"` + NeedScore int `json:"needScore"` + Score int `json:"score"` + GuardLevel int `json:"guard_level"` + } `json:"ownInfo"` + TipsText string `json:"tips_text"` + ValueText string `json:"value_text"` + } `json:"data"` +} diff --git a/Reply/Reply.go b/Reply/Reply.go index 0357a31..be1a647 100644 --- a/Reply/Reply.go +++ b/Reply/Reply.go @@ -324,9 +324,13 @@ func (replyF) user_toast_msg(s string) { // HeartBeat-心跳用来传递人气值 var ( - renqi_old int - pperm_old float64 - continuity int + renqi_last int + renqi_old int + watched_old float64 + onlinenum_old int + renqi_l float64 + watched_l float64 + onlinenum_l float64 ) func (replyF) heartbeat(s int) { @@ -337,47 +341,56 @@ func (replyF) heartbeat(s int) { if s == 1 { return } //人气为1,不输出 - var ( - tmp string - tmp2 string - ) - if renqi_old != 0 { - if s > renqi_old { - tmp += `+` - } - tmp += fmt.Sprintf("%.1f%%", 100*float64(s-renqi_old)/float64(renqi_old)) - if s > renqi_old { - continuity += 1 - if continuity > 2 { - tmp = tmp + ` 连续上升` + strconv.Itoa(continuity) - } else if continuity < 0 { - continuity = 1 + if renqi_last != s { + var ( + tmp string + watchPerMin float64 = float64(c.C.Watched) / float64(time.Since(c.C.Live_Start_Time)/time.Minute) + tmp1 string + tmp2 string + ) + if renqi_old != 0 { + renqi_l = (renqi_l + 100*float64(s-renqi_old)/float64(renqi_old)) / 2 + if renqi_l > 0 { + tmp = `+` + } else if renqi_l == 0 { + tmp = `=` } - } else if s < renqi_old { - continuity -= 1 - if continuity < -2 { - tmp = tmp + ` 连续下降` + strconv.Itoa(-continuity) - } else if continuity > 0 { - continuity = -1 + tmp += fmt.Sprintf("%.1f%%", renqi_l) + tmp = `(` + tmp + `)` + } else { + tmp = "(=0.0%)" + } + if watched_old != 0 { + watched_l = (watched_l + 100*float64(watchPerMin-watched_old)/float64(watched_old)) / 2 + if watched_l > 0 { + tmp1 = `+` + } else if watched_l == 0 { + tmp1 = `=` } + tmp1 += fmt.Sprintf("%.1f%%", watched_l) + tmp1 = `(` + tmp1 + `)` + } else { + tmp1 = "(=0.0%)" } - tmp = `(` + tmp + `)` - } - - var pperm = float64(c.C.Watched) / float64(time.Since(c.C.Live_Start_Time)/time.Minute) - if pperm_old != 0 { - tmp2 += fmt.Sprintf("(avg: %.1f人/分 ", pperm) - if pperm-pperm_old > 0 { - tmp2 += `+` + if onlinenum_old != 0 { + onlinenum_l = (onlinenum_l + 100*float64(c.C.OnlineNum-onlinenum_old)/float64(onlinenum_old)) / 2 + if onlinenum_l > 0 { + tmp2 = `+` + } else if onlinenum_l == 0 { + tmp2 = `=` + } + tmp2 += fmt.Sprintf("%.1f%%", onlinenum_l) + tmp2 = `(` + tmp2 + `)` + } else { + tmp2 = "(=0.0%)" } - tmp2 += fmt.Sprintf("%.1f", pperm-pperm_old) + `)` - } - if renqi_old != s { - fmt.Printf("\t人气:%d %s\n\t观看人数:%d %s\n", s, tmp, c.C.Watched, tmp2) - pperm_old = pperm + fmt.Printf("+----\n|当前人气:%s%d\n|平均观看:%s%d\n|在线人数:%s%d\n|平均意愿:%.1f\n+----\n", tmp, s, tmp1, int(watchPerMin), tmp2, c.C.OnlineNum, onlinenum_l+watched_l) + renqi_old = s + watched_old = watchPerMin + onlinenum_old = c.C.OnlineNum } + renqi_last = s reply_log.Base_add(`人气`).Log_show_control(false).L(`I: `, "当前人气", s) - renqi_old = s } // Msg-房间特殊活动 diff --git a/bili_danmu.go b/bili_danmu.go index 073c16a..7b94b8a 100644 --- a/bili_danmu.go +++ b/bili_danmu.go @@ -32,6 +32,7 @@ func init() { c.C.Danmu_Main_mq.Push_tag(`new day`, nil) old = now } + c.C.Danmu_Main_mq.Push_tag(`every100s`, nil) time.Sleep(time.Second * time.Duration(100)) } }() @@ -100,20 +101,21 @@ func Start() { //使用带tag的消息队列在功能间传递消息 c.C.Danmu_Main_mq.Pull_tag(msgq.FuncMap{ - `flash_room`: func(_ interface{}) bool { //房间重进 + `flash_room`: func(_ any) bool { //房间重进 select { case flash_room_chan <- struct{}{}: default: } return false }, - `change_room`: func(_ interface{}) bool { //房间改变 - c.C.Rev = 0.0 // 营收 - c.C.Renqi = 1 // 人气置1 - c.C.Watched = 0 // 观看人数 - c.C.GuardNum = 0 // 舰长数 - c.C.Note = `` // 分区排行 - c.C.Uname = `` // 主播id + `change_room`: func(_ any) bool { //房间改变 + c.C.Rev = 0.0 // 营收 + c.C.Renqi = 1 // 人气置1 + c.C.Watched = 0 // 观看人数 + c.C.OnlineNum = 0 // 在线人数 + c.C.GuardNum = 0 // 舰长数 + c.C.Note = `` // 分区排行 + c.C.Uname = `` // 主播id c.C.Title = `` c.C.Wearing_FansMedal = 0 for len(change_room_chan) != 0 { @@ -122,24 +124,24 @@ func Start() { change_room_chan <- struct{}{} return false }, - `c.Rev_add`: func(data interface{}) bool { //收入 + `c.Rev_add`: func(data any) bool { //收入 c.C.Rev += data.(float64) return false }, - `c.Renqi`: func(data interface{}) bool { //人气更新 + `c.Renqi`: func(data any) bool { //人气更新 if tmp, ok := data.(int); ok { c.C.Renqi = tmp } return false }, - `gtk_close`: func(_ interface{}) bool { //gtk关闭信号 + `gtk_close`: func(_ any) bool { //gtk关闭信号 interrupt <- os.Interrupt return false }, }) //单独,避免队列执行耗时block从而无法接收更多消息 c.C.Danmu_Main_mq.Pull_tag(msgq.FuncMap{ - `pm`: func(data interface{}) bool { //私信 + `pm`: func(data any) bool { //私信 if tmp, ok := data.(send.Pm_item); ok { send.Send_pm(tmp.Uid, tmp.Msg) } @@ -175,7 +177,7 @@ func Start() { danmulog.L(`I: `, "连接到房间", c.C.Roomid) Cookie := make(map[string]string) - c.C.Cookie.Range(func(k, v interface{}) bool { + c.C.Cookie.Range(func(k, v any) bool { Cookie[k.(string)] = v.(string) return true }) @@ -244,19 +246,28 @@ func Start() { //订阅消息,以便刷新舰长数 F.Get(&c.C).Get(`GuardNum`) + // 在线人数 + F.Get(&c.C).Get(`getOnlineGoldRank`) //使用带tag的消息队列在功能间传递消息 c.C.Danmu_Main_mq.Pull_tag(msgq.FuncMap{ - `guard_update`: func(_ interface{}) bool { //舰长更新 + `guard_update`: func(_ any) bool { //舰长更新 go F.Get(&c.C).Get(`GuardNum`) return false }, - `flash_room`: func(data interface{}) bool { //重进房时退出当前房间 + `flash_room`: func(data any) bool { //重进房时退出当前房间 return true }, - `change_room`: func(data interface{}) bool { //换房时退出当前房间 + `change_room`: func(data any) bool { //换房时退出当前房间 return true }, - `new day`: func(_ interface{}) bool { //日期更换 + `every100s`: func(_ any) bool { //每100s + if v, ok := c.C.K_v.LoadV("下播后不记录人气观看人数").(bool); ok && v && c.C.Liveing { + // 在线人数 + F.Get(&c.C).Get(`getOnlineGoldRank`) + } + return false + }, + `new day`: func(_ any) bool { //日期更换 //每日签到 F.Dosign() // //获取用户版本 不再需要 diff --git a/cmd/cmd.go b/cmd/cmd.go index ffdf567..3f1933a 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -190,7 +190,7 @@ func Cmd() { fmt.Println(`营收:`, fmt.Sprintf("¥%.2f", c.C.Rev)) } fmt.Println(`舰长数:`, c.C.GuardNum) - fmt.Println(`分区排行:`, c.C.Note, `人气:`, c.C.Renqi, `观看人数:`, c.C.Watched) + fmt.Println(`分区排行:`, c.C.Note, `人气:`, c.C.Renqi, `观看人数:`, c.C.Watched, `在线人数:`, c.C.OnlineNum) for _, v := range c.C.Stream_url { fmt.Println(`直播Web服务:`, v) } -- 2.39.2