Rev float64 //营收
Renqi int //人气
Watched int //观看人数
+ OnlineNum int //在线人数
GuardNum int //舰长数
ParentAreaID int //父分区
AreaID int //子分区
} //超额请求阻塞,超时将取消
var (
- api_can_get = map[string][]func() []string{
+ api_can_get = map[string][]func() (missKey []string){
`Cookie`: { //Cookie
c.Get_cookie,
},
`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
},
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)
}
}
+// 获取在线人数
+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: `, `完成`)
--- /dev/null
+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"`
+}
// 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) {
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-房间特殊活动
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))
}
}()
//使用带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 {
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)
}
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
})
//订阅消息,以便刷新舰长数
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()
// //获取用户版本 不再需要
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)
}