LiveBuvidUpdated time.Time `json:"-"` //LIVE_BUVID更新时间
Stream_url *url.URL `json:"-"` //直播Web服务
Proxy string `json:"-"` //全局代理
+ SerLocation int `json:"-"` //服务器时区
AcceptQn map[int]string `json:"-"` //允许的直播流质量
Qn map[int]string `json:"-"` //全部直播流质量
// StreamType StreamType `json:"streamType"` //当前直播流类型
LiveBuvidUpdated: t.LiveBuvidUpdated,
Stream_url: t.Stream_url,
Proxy: t.Proxy,
+ SerLocation: t.SerLocation,
AcceptQn: syncmap.Copy(t.AcceptQn),
Qn: syncmap.Copy(t.Qn),
// StreamType: t.StreamType,
t.Proxy = val.(string)
}
+ if val, exist := t.K_v.LoadV("服务器时区").(float64); exist && val != 0 {
+ t.SerLocation = int(val)
+ }
+
// 配置直播流类型
if val, exist := t.K_v.Load("直播流类型"); exist {
if _, ok := t.AllStreamType[val.(string)]; !ok {
import (
"fmt"
+ "sync"
c "github.com/qydysky/bili_danmu/CV"
crypto "github.com/qydysky/part/crypto"
// 公私钥加密
var (
- clog = c.C.Log.Base(`cookie加密`)
- pub []byte
- pri []byte
+ clog = c.C.Log.Base(`cookie加密`)
+ pub []byte
+ pri []byte
+ cookieLock sync.RWMutex
)
func CookieGet() []byte {
clog := clog.Base_add(`获取`)
+
+ cookieLock.RLock()
+ defer cookieLock.RUnlock()
+
if len(pri) == 0 {
if priS, ok := c.C.K_v.LoadV(`cookie解密私钥`).(string); ok && priS != `` {
if d, e := crypto.FileLoad(priS); e != nil {
func CookieSet(source []byte) {
clog := clog.Base_add(`设置`)
+
+ cookieLock.Lock()
+ defer cookieLock.Unlock()
+
if len(pub) == 0 {
if pubS, ok := c.C.K_v.LoadV(`cookie加密公钥`).(string); ok && pubS != `` {
if d, e := crypto.FileLoad(pubS); e != nil {
var api_limit = limit.New(2, "1s", "30s") //频率限制2次/s,最大等待时间30s
var biliApi = cmp.Get(id, func(ba biliApiInter) biliApiInter {
+ ba.SetLocation(c.C.SerLocation)
ba.SetProxy(c.C.Proxy)
ba.SetReqPool(c.C.ReqPool)
return ba
return &GetFunc{Common: c}
}
-func (c *GetFunc) Get(key string) {
+func (t *GetFunc) Get(key string) {
apilog := apilog.Base_add(`Get`)
- current := c.count.Add(1)
- defer c.count.Add(-1)
+ current := t.count.Add(1)
+ defer t.count.Add(-1)
if current > 10 {
apilog.L(`E: `, `max loop`)
var (
api_can_get = map[string][]func() (missKey []string){
`Cookie`: { //Cookie
- c.Get_cookie,
+ t.Get_cookie,
},
`Uid`: { //用戶uid
- c.GetUid,
+ t.GetUid,
},
`UpUid`: { //主播uid
- c.getRoomBaseInfo,
- c.getInfoByRoom,
- c.getRoomPlayInfo,
- c.Html,
+ t.getRoomBaseInfo,
+ t.getInfoByRoom,
+ t.getRoomPlayInfo,
+ t.Html,
},
`Live_Start_Time`: { //直播开始时间
- c.getRoomBaseInfo,
- c.getInfoByRoom,
- c.getRoomPlayInfo,
- c.Html,
+ t.getRoomBaseInfo,
+ t.getInfoByRoom,
+ t.getRoomPlayInfo,
+ t.Html,
},
`Liveing`: { //是否在直播
- c.getRoomBaseInfo,
- c.getInfoByRoom,
- c.getRoomPlayInfo,
- c.Html,
+ t.getRoomBaseInfo,
+ t.getInfoByRoom,
+ t.getRoomPlayInfo,
+ t.Html,
},
`Title`: { //直播间标题
- c.getRoomBaseInfo,
- c.getInfoByRoom,
- c.Html,
+ t.getRoomBaseInfo,
+ t.getInfoByRoom,
+ t.Html,
},
`Uname`: { //主播名
- c.getRoomBaseInfo,
- c.getInfoByRoom,
- c.Html,
+ t.getRoomBaseInfo,
+ t.getInfoByRoom,
+ t.Html,
},
`ParentAreaID`: { //分区
- c.getRoomBaseInfo,
- c.getInfoByRoom,
- c.Html,
+ t.getRoomBaseInfo,
+ t.getInfoByRoom,
+ t.Html,
},
`AreaID`: { //子分区
- c.getRoomBaseInfo,
- c.getInfoByRoom,
- c.Html,
+ t.getRoomBaseInfo,
+ t.getInfoByRoom,
+ t.Html,
},
`Roomid`: { //房间id
- c.missRoomId,
+ t.missRoomId,
},
`GuardNum`: { //舰长数
- c.Get_guardNum,
- c.getInfoByRoom,
- c.getRoomPlayInfo,
- c.Html,
+ t.Get_guardNum,
+ t.getInfoByRoom,
+ t.getRoomPlayInfo,
+ t.Html,
},
`Note`: { //分区排行
- c.getPopularAnchorRank,
- // c.Get_HotRank,
- c.getInfoByRoom,
- c.Html,
+ t.getPopularAnchorRank,
+ // t.Get_HotRank,
+ t.getInfoByRoom,
+ t.Html,
},
`Locked`: { //直播间是否被封禁
- c.getInfoByRoom,
- c.Html,
+ t.getInfoByRoom,
+ t.Html,
},
`Live_qn`: { //当前直播流质量
- c.getRoomPlayInfo,
- c.Html,
+ t.getRoomPlayInfo,
+ t.Html,
},
`AcceptQn`: { //允许的清晰度
- c.getRoomPlayInfo,
- c.Html,
+ t.getRoomPlayInfo,
+ t.Html,
},
`Live`: { //直播流链接
- c.getRoomPlayInfoByQn,
- c.getRoomPlayInfo,
- c.Html,
+ t.getRoomPlayInfoByQn,
+ t.getRoomPlayInfo,
+ t.Html,
},
`Token`: { //弹幕钥
- c.getDanmuInfo,
+ t.getDanmuInfo,
},
`WSURL`: { //弹幕链接
- c.getDanmuInfo,
+ t.getDanmuInfo,
},
// `VERSION`:[]func()([]string){//客户版本 不再需要
// Get_Version,
// },
`LIVE_BUVID`: { //LIVE_BUVID
- c.Get_LIVE_BUVID,
+ t.Get_LIVE_BUVID,
},
`CheckSwitch_FansMedal`: { //切换粉丝牌
- c.CheckSwitch_FansMedal,
+ t.CheckSwitch_FansMedal,
},
`getOnlineGoldRank`: { //切换粉丝牌
- c.getOnlineGoldRank,
+ t.getOnlineGoldRank,
},
}
// 验证是否有效
check = map[string]func() (valid bool){
`Uid`: func() bool { //用戶uid
- return c.Uid != 0
+ return t.Uid != 0
},
`UpUid`: func() bool { //主播uid
- return c.UpUid != 0
+ return t.UpUid != 0
},
`Live_Start_Time`: func() bool { //直播开始时间
- return c.Live_Start_Time != time.Time{}
+ return t.Live_Start_Time != time.Time{}
},
`Liveing`: func() bool { //是否在直播
return true
},
`Title`: func() bool { //直播间标题
- return c.Title != ``
+ return t.Title != ``
},
`Uname`: func() bool { //主播名
- return c.Uname != ``
+ return t.Uname != ``
},
`ParentAreaID`: func() bool { //分区
- return c.ParentAreaID != 0
+ return t.ParentAreaID != 0
},
`AreaID`: func() bool { //子分区
- return c.AreaID != 0
+ return t.AreaID != 0
},
`Roomid`: func() bool { //房间id
- return c.Roomid != 0
+ return t.Roomid != 0
},
`GuardNum`: func() bool { //舰长数
- return c.GuardNum != 0
+ return t.GuardNum != 0
},
`Note`: func() bool { //分区排行
- return c.Note != ``
+ return t.Note != ``
},
`Locked`: func() bool { //直播间是否被封禁
return true
},
`Live_qn`: func() bool { //当前直播流质量
- return c.Live_qn != 0
+ return t.Live_qn != 0
},
`AcceptQn`: func() bool { //允许的清晰度
- return len(c.AcceptQn) != 0
+ return len(t.AcceptQn) != 0
},
`Live`: func() bool { //直播流链接
- return len(c.Live) != 0
+ return len(t.Live) != 0
},
`Token`: func() bool { //弹幕钥
- return c.Token != ``
+ return t.Token != ``
},
`WSURL`: func() bool { //弹幕链接
- return len(c.WSURL) != 0
+ return len(t.WSURL) != 0
},
// `VERSION`:func()(bool){//客户版本 不再需要
- // return c.VERSION != `2.0.11`
+ // return t.VERSION != `2.0.11`
// },
`LIVE_BUVID`: func() bool { //LIVE_BUVID
- return c.LiveBuvidUpdated.After(time.Now().Add(-time.Hour))
+ return t.LiveBuvidUpdated.After(time.Now().Add(-time.Hour))
},
`CheckSwitch_FansMedal`: func() bool { //切换粉丝牌
return true
for i := 0; i < len(fList); i++ {
apilog.Log_show_control(false).L(`T: `, `Get`, key)
- c.l.Lock()
+ t.l.Lock()
missKey := fList[i]()
- c.l.Unlock()
+ t.l.Unlock()
if len(missKey) > 0 {
apilog.L(`T: `, `missKey when get`, key, missKey)
for _, misskeyitem := range missKey {
if checkf, ok := check[misskeyitem]; ok {
- c.l.RLock()
+ t.l.RLock()
if checkf() {
- c.l.RUnlock()
+ t.l.RUnlock()
continue
}
- c.l.RUnlock()
+ t.l.RUnlock()
}
if misskeyitem == key {
apilog.L(`W: `, `missKey equrt key`, key, missKey)
continue
}
- c.Get(misskeyitem)
+ t.Get(misskeyitem)
}
- c.l.Lock()
+ t.l.Lock()
missKey := fList[i]()
- c.l.Unlock()
+ t.l.Unlock()
if len(missKey) > 0 {
apilog.L(`W: `, `missKey when get`, key, missKey)
}
if checkf, ok := check[key]; ok {
- c.l.RLock()
+ t.l.RLock()
if checkf() {
- c.l.RUnlock()
+ t.l.RUnlock()
break
} else {
- c.l.RUnlock()
+ t.l.RUnlock()
apilog.L(`W: `, `check fail`, key)
- // c.Get(key)
+ // t.Get(key)
}
}
}
}
}
-func (c *GetFunc) GetUid() (missKey []string) {
- if uid, ok := c.Cookie.LoadV(`DedeUserID`).(string); !ok { //cookie中无DedeUserID
+func (t *GetFunc) GetUid() (missKey []string) {
+ if uid, ok := t.Cookie.LoadV(`DedeUserID`).(string); !ok { //cookie中无DedeUserID
missKey = append(missKey, `Cookie`)
} else if uid, e := strconv.Atoi(uid); e != nil {
missKey = append(missKey, `Cookie`)
} else {
- c.Uid = uid
+ t.Uid = uid
}
return
}
}
}
-func (c *GetFunc) missRoomId() (missKey []string) {
+func (t *GetFunc) missRoomId() (missKey []string) {
apilog.Base_add(`missRoomId`).L(`E: `, `missRoomId`)
return
}
-func (c *GetFunc) getRoomBaseInfo() (missKey []string) {
+func (t *GetFunc) getRoomBaseInfo() (missKey []string) {
fkey := `getRoomBaseInfo`
- if _, ok := c.Cache.Load(fkey); ok {
+ if _, ok := t.Cache.Load(fkey); ok {
return
}
apilog := apilog.Base_add(`getRoomBaseInfo`)
- if c.Roomid == 0 {
+ if t.Roomid == 0 {
missKey = append(missKey, `Roomid`)
return
}
//使用其他api
- if err, res := biliApi.GetRoomBaseInfo(c.Roomid); err != nil {
+ if err, res := biliApi.GetRoomBaseInfo(t.Roomid); err != nil {
apilog.L(`E: `, err)
return
} else {
- c.UpUid = res.UpUid
- c.Uname = res.Uname
- c.ParentAreaID = res.ParentAreaID
- c.AreaID = res.AreaID
- c.Title = res.Title
- c.Live_Start_Time = res.LiveStartTime
- c.Liveing = res.Liveing
- c.Roomid = res.RoomID
+ t.UpUid = res.UpUid
+ t.Uname = res.Uname
+ t.ParentAreaID = res.ParentAreaID
+ t.AreaID = res.AreaID
+ t.Title = res.Title
+ t.Live_Start_Time = res.LiveStartTime
+ t.Liveing = res.Liveing
+ t.Roomid = res.RoomID
}
- c.Cache.Store(fkey, nil, time.Second*2)
+ t.Cache.Store(fkey, nil, time.Second*2)
return
}
-func (c *GetFunc) getInfoByRoom() (missKey []string) {
+func (t *GetFunc) getInfoByRoom() (missKey []string) {
fkey := `getInfoByRoom`
- if _, ok := c.Cache.Load(fkey); ok {
+ if _, ok := t.Cache.Load(fkey); ok {
return
}
apilog := apilog.Base_add(`getInfoByRoom`)
- if c.Roomid == 0 {
+ if t.Roomid == 0 {
missKey = append(missKey, `Roomid`)
return
}
//使用其他api
- if err, res := biliApi.GetInfoByRoom(c.Roomid); err != nil {
+ if err, res := biliApi.GetInfoByRoom(t.Roomid); err != nil {
apilog.L(`E: `, err)
return
} else {
- c.UpUid = res.UpUid
- c.Uname = res.Uname
- c.ParentAreaID = res.ParentAreaID
- c.AreaID = res.AreaID
- c.Title = res.Title
- c.Live_Start_Time = res.LiveStartTime
- c.Liveing = res.Liveing
- c.Roomid = res.RoomID
- c.GuardNum = res.GuardNum
- c.Note = res.Note
- c.Locked = res.Locked
+ t.UpUid = res.UpUid
+ t.Uname = res.Uname
+ t.ParentAreaID = res.ParentAreaID
+ t.AreaID = res.AreaID
+ t.Title = res.Title
+ t.Live_Start_Time = res.LiveStartTime
+ t.Liveing = res.Liveing
+ t.Roomid = res.RoomID
+ t.GuardNum = res.GuardNum
+ t.Note = res.Note
+ t.Locked = res.Locked
}
- c.Cache.Store(fkey, nil, time.Second*2)
+ t.Cache.Store(fkey, nil, time.Second*2)
return
}
return
}
-func (c *GetFunc) getDanmuInfo() (missKey []string) {
- if c.Roomid == 0 {
+func (t *GetFunc) getDanmuInfo() (missKey []string) {
+ if t.Roomid == 0 {
missKey = append(missKey, `Roomid`)
}
- if c.LiveBuvidUpdated.Before(time.Now().Add(-time.Hour)) {
+ if t.LiveBuvidUpdated.Before(time.Now().Add(-time.Hour)) {
missKey = append(missKey, `LIVE_BUVID`)
}
if len(missKey) > 0 {
}
//GetDanmuInfo
- if err, res := biliApi.GetDanmuInfo(c.Roomid); err != nil {
+ if err, res := biliApi.GetDanmuInfo(t.Roomid); err != nil {
apilog.L(`E: `, err)
return
} else {
- c.Token = res.Token
- c.WSURL = res.WSURL
+ t.Token = res.Token
+ t.WSURL = res.WSURL
}
return
}
}
// 获取其他Cookie
-// func (c *GetFunc) Get_other_cookie() {
+// func (t *GetFunc) Get_other_cookie() {
// apilog := apilog.Base_add(`获取其他Cookie`)
// r := c.ReqPool.Get()
return
}
-func (c *GetFunc) CheckSwitch_FansMedal() (missKey []string) {
+func (t *GetFunc) CheckSwitch_FansMedal() (missKey []string) {
- if c.LiveBuvidUpdated.Before(time.Now().Add(-time.Hour)) {
+ if t.LiveBuvidUpdated.Before(time.Now().Add(-time.Hour)) {
missKey = append(missKey, `LIVE_BUVID`)
}
- if c.UpUid == 0 {
+ if t.UpUid == 0 {
missKey = append(missKey, `UpUid`)
}
if len(missKey) > 0 {
}
Cookie := make(map[string]string)
- c.Cookie.Range(func(k, v interface{}) bool {
+ t.Cookie.Range(func(k, v interface{}) bool {
Cookie[k.(string)] = v.(string)
return true
})
{ //获取当前牌子,验证是否本直播间牌子
- res := Get_weared_medal(c.Uid, c.UpUid)
+ res := Get_weared_medal(t.Uid, t.UpUid)
- c.Wearing_FansMedal = res.Roominfo.RoomID //更新佩戴信息
- if res.TargetID == c.UpUid {
+ t.Wearing_FansMedal = res.Roominfo.RoomID //更新佩戴信息
+ if res.TargetID == t.UpUid {
return
}
}
var medal_id int //将要使用的牌子id
//检查是否有此直播间的牌子
{
- medal_list := Get_list_in_room(c.Roomid, c.UpUid)
+ medal_list := Get_list_in_room(t.Roomid, t.UpUid)
for _, v := range medal_list {
- if v.TargetID != c.UpUid {
+ if v.TargetID != t.UpUid {
continue
}
medal_id = v.MedalID
}
if medal_id == 0 { //无牌
apilog.L(`I: `, `无主播粉丝牌`)
- if c.Wearing_FansMedal == 0 { //当前没牌
+ if t.Wearing_FansMedal == 0 { //当前没牌
return
}
}
} else {
apilog.L(`I: `, `自动切换粉丝牌 id:`, medal_id)
}
- c.Wearing_FansMedal = medal_id //更新佩戴信息
+ t.Wearing_FansMedal = medal_id //更新佩戴信息
return
}
}
}
}
-func (c *GetFunc) SearchUP(s string) (list []struct {
+func (t *GetFunc) SearchUP(s string) (list []struct {
Roomid int
Uname string
Is_live bool
}
// bilibili wrid wts 计算
-func (c *GetFunc) getWridWts(query string, imgURL, subURL string, customWts ...string) (w_rid, wts string) {
+func (t *GetFunc) getWridWts(query string, imgURL, subURL string, customWts ...string) (w_rid, wts string) {
wbi := imgURL[strings.LastIndex(imgURL, "/")+1:strings.LastIndex(imgURL, ".")] +
subURL[strings.LastIndex(subURL, "/")+1:strings.LastIndex(subURL, ".")]
type biliApiInter interface {
SetReqPool(pool *pool.Buf[reqf.Req])
SetProxy(proxy string)
+ SetLocation(secOfTimeZone int) // east positive
SetCookies(cookies []*http.Cookie)
GetCookies() (cookies []*http.Cookie)
GetCookie(name string) (error, string)
show(`输入错误`, load_face("0room"))
} else {
c.C.Roomid = i
- c.C.Danmu_Main_mq.Push_tag(`change_room`, nil)
+ c.C.Danmu_Main_mq.Push_tag(`change_room`, i)
}
} else {
show(`房间号输入为空`, load_face("0room"))
}
for exitSign := false; !exitSign; {
- if c.C.Roomid == 0 {
+ common := c.C.Copy()
+
+ if common.Roomid == 0 {
fmt.Println("回车查看指令")
ctx, cancel := context.WithCancel(mainCtx)
- cancel1, c := c.C.Danmu_Main_mq.Pull_tag_chan(`change_room`, 1, ctx)
+ cancel1, c := common.Danmu_Main_mq.Pull_tag_chan(`change_room`, 1, ctx)
select {
- case <-c:
+ case roomid := <-c:
+ common.Roomid = roomid.(int)
case <-interrupt_chan:
exitSign = true
}
cancel1()
cancel()
} else {
- fmt.Print("房间号: ", strconv.Itoa(c.C.Roomid), "\n")
+ fmt.Print("房间号: ", strconv.Itoa(common.Roomid), "\n")
}
if exitSign {
//附加功能 自动发送即将过期礼物
go reply.AutoSend_silver_gift()
//获取热门榜
- F.Get(c.C).Get(`Note`)
+ F.Get(common).Get(`Note`)
- danmulog.L(`I: `, "连接到房间", c.C.Roomid)
+ danmulog.L(`I: `, "连接到房间", common.Roomid)
Cookie := make(map[string]string)
- c.C.Cookie.Range(func(k, v any) bool {
+ common.Cookie.Range(func(k, v any) bool {
Cookie[k.(string)] = v.(string)
return true
})
- F.Get(c.C).Get(`Liveing`)
// 检查与切换粉丝牌,只在cookie存在时启用
- F.Get(c.C).Get(`CheckSwitch_FansMedal`)
-
- // 直播状态
- if c.C.Liveing {
- danmulog.L(`I: `, "直播中")
- } else {
- danmulog.L(`I: `, "未直播")
- }
+ F.Get(common).Get(`CheckSwitch_FansMedal`)
// 对每个弹幕服务器尝试
- F.Get(c.C).Get(`WSURL`)
+ F.Get(common).Get(`WSURL`)
aliveT := time.Now().Add(3 * time.Hour)
- for i, exitloop := 0, false; !exitloop && i < len(c.C.WSURL) && time.Now().Before(aliveT); {
- v := c.C.WSURL[i]
+ for i, exitloop := 0, false; !exitloop && i < len(common.WSURL) && time.Now().Before(aliveT); {
+ v := common.WSURL[i]
//ws启动
danmulog.L(`T: `, "连接 "+v)
u, _ := url.Parse(v)
ws_c, err := ws.New_client(&ws.Client{
Url: v,
TO: 35 * 1000,
- Proxy: c.C.Proxy,
+ Proxy: common.Proxy,
Func_abort_close: func() { danmulog.L(`I: `, `服务器连接中断`) },
Func_normal_close: func() { danmulog.L(`I: `, `服务器连接关闭`) },
Header: map[string]string{
// auth
{
wsmsg.PushLock_tag(`send`, &ws.WsMsg{
- Msg: F.HelloGen(c.C.Roomid, c.C.Token),
+ Msg: F.HelloGen(common.Roomid, common.Token),
})
waitCheckAuth, cancel := context.WithTimeout(mainCtx, 5*time.Second)
doneAuth := wsmsg.Pull_tag_only(`rec`, func(wm *ws.WsMsg) (disable bool) {
}
}
- danmulog.L(`I: `, "已连接到房间", c.C.Uname, `(`, c.C.Roomid, `)`)
- reply.Gui_show(`进入直播间: `+c.C.Uname+` (`+strconv.Itoa(c.C.Roomid)+`)`, `0room`)
- if c.C.Title != `` {
- danmulog.L(`I: `, `房间标题: `+c.C.Title)
- reply.Gui_show(`房间标题: `+c.C.Title, `0room`)
+ danmulog.L(`I: `, "已连接到房间", common.Uname, `(`, common.Roomid, `)`)
+ reply.Gui_show(`进入直播间: `+common.Uname+` (`+strconv.Itoa(common.Roomid)+`)`, `0room`)
+ if common.Title != `` {
+ danmulog.L(`I: `, `房间标题: `+common.Title)
+ reply.Gui_show(`房间标题: `+common.Title, `0room`)
+ }
+
+ // 直播状态
+ if F.Get(common).Get(`Liveing`); common.Liveing {
+ danmulog.L(`I: `, "直播中")
+ } else {
+ danmulog.L(`I: `, "未直播")
}
// 处理ws消息
var cancelDeal = wsmsg.Pull_tag(map[string]func(*ws.WsMsg) (disable bool){
`rec`: func(wm *ws.WsMsg) (disable bool) {
- go reply.Reply(c.C, wm.Msg)
+ go reply.Reply(common, wm.Msg)
return false
},
`close`: func(_ *ws.WsMsg) (disable bool) {
}()
// 刷新舰长数
- F.Get(c.C).Get(`GuardNum`)
+ F.Get(common).Get(`GuardNum`)
// 在线人数
- F.Get(c.C).Get(`getOnlineGoldRank`)
+ F.Get(common).Get(`getOnlineGoldRank`)
//验证cookie
if missKey := F.CookieCheck([]string{
`bili_jct`,
{ //附加功能 进房间发送弹幕 直播流保存 每日签到
go F.Dosign()
go reply.Entry_danmu()
- if _, e := recStartEnd.RecStartCheck.Run(mainCtx, c.C); e == nil {
- go reply.StreamOStart(c.C.Copy(), c.C.Roomid)
+ if _, e := recStartEnd.RecStartCheck.Run(mainCtx, common); e == nil {
+ go reply.StreamOStart(common, common.Roomid)
} else {
- danmulog.Base("功能", "指定房间录制区间").L(`I: `, c.C.Roomid, e)
+ danmulog.Base("功能", "指定房间录制区间").L(`I: `, common.Roomid, e)
}
- go F.RoomEntryAction(c.C.Roomid)
+ go F.RoomEntryAction(common.Roomid)
}
//当前ws
{
// 处理各种指令
- var cancelfunc = c.C.Danmu_Main_mq.Pull_tag(msgq.FuncMap{
+ var cancelfunc = common.Danmu_Main_mq.Pull_tag(msgq.FuncMap{
`interrupt`: func(_ any) (disable bool) {
exitloop = true
exitSign = true
},
`exit_room`: func(_ any) bool { //退出当前房间
exitloop = true
- reply.StreamOStop(c.C.Roomid)
- danmulog.L(`I: `, "退出房间", c.C.Roomid)
- c.C.Roomid = 0
+ reply.StreamOStop(common.Roomid)
+ danmulog.L(`I: `, "退出房间", common.Roomid)
+ common.Roomid = 0
ws_c.Close()
return true
},
- `change_room`: func(_ any) bool { //换房时退出当前房间
+ `change_room`: func(roomid any) bool { //换房时退出当前房间
+ common.Roomid = roomid.(int)
exitloop = true
ws_c.Close()
- if v, ok := c.C.K_v.LoadV(`仅保存当前直播间流`).(bool); ok && v {
- reply.StreamOStopOther(c.C.Roomid) //停止其他房间录制
+ if v, ok := common.K_v.LoadV(`仅保存当前直播间流`).(bool); ok && v {
+ reply.StreamOStopOther(common.Roomid) //停止其他房间录制
}
return true
},
`flash_room`: func(_ any) bool { //重进房时退出当前房间
- go F.Get(c.C).Get(`WSURL`)
+ go F.Get(common).Get(`WSURL`)
ws_c.Close()
return true
},
`guard_update`: func(_ any) bool { //舰长更新
- go F.Get(c.C).Get(`GuardNum`)
+ go F.Get(common).Get(`GuardNum`)
return false
},
`every100s`: func(_ any) bool { //每100s
if time.Now().After(aliveT) {
- c.C.Danmu_Main_mq.Push_tag(`flash_room`, nil)
+ common.Danmu_Main_mq.Push_tag(`flash_room`, nil)
return false
}
- if v, ok := c.C.K_v.LoadV("下播后不记录人气观看人数").(bool); ok && v && !c.C.Liveing {
+ if v, ok := common.K_v.LoadV("下播后不记录人气观看人数").(bool); ok && v && !common.Liveing {
return false
}
// 在线人数
- go F.Get(c.C).Get(`getOnlineGoldRank`)
+ go F.Get(common).Get(`getOnlineGoldRank`)
return false
},
`new day`: func(_ any) bool { //日期更换
//每日签到
F.Dosign()
//每日兑换硬币
- F.Get(c.C).Silver_2_coin()
+ F.Get(common).Silver_2_coin()
//附加功能 每日发送弹幕
reply.Entry_danmu()
//附加功能 保持牌子点亮
fmt.Print("\n")
if room, ok := liveList[inputs]; ok {
c.C.Roomid = room
- c.C.Danmu_Main_mq.Push_tag(`change_room`, nil)
+ c.C.Danmu_Main_mq.Push_tag(`change_room`, room)
continue
} else {
cmdlog.L(`W: `, "输入错误", inputs)
}
fmt.Println(c.C.Uname, c.C.Title, living)
}
- {
- if c.C.Liveing {
- d := time.Since(c.C.Live_Start_Time).Round(time.Second)
- h := d / time.Hour
- d -= h * time.Hour
- m := d / time.Minute
- d -= m * time.Minute
- s := d / time.Second
- fmt.Println(`已直播时长:`, fmt.Sprintf("%02d:%02d:%02d", h, m, s))
- }
+ if c.C.Liveing {
+ fmt.Println(`已直播时长:`, (time.Time{}).Add(time.Since(c.C.Live_Start_Time)).Format(time.TimeOnly))
}
{
fmt.Println(`营收:`, fmt.Sprintf("¥%.2f", c.C.Rev))
if room, err := strconv.Atoi(inputs[1:]); err == nil {
c.C.Roomid = room
cmdlog.L(`I: `, "进入房间", room)
- c.C.Danmu_Main_mq.Push_tag(`change_room`, nil)
+ c.C.Danmu_Main_mq.Push_tag(`change_room`, room)
continue
}
cmdlog.L(`W: `, "无效指令("+inputs+")")
"生成pgo-help":"将在退出后生成pgo文件在指定路径,default.pgo将有助于下次构建的优化,但会导致gc频繁,构建缓慢,为空时不生成",
"生成pgo":"",
"登陆二维码-白":"OO",
- "登陆二维码-黑":" "
+ "登陆二维码-黑":" ",
+ "服务器时区-help":"用于正确解析服务器响应中的时间,整数,单位秒,整数是UTC以东,默认0",
+ "服务器时区":0
}
\ No newline at end of file
go 1.22.2
require (
- github.com/gotk3/gotk3 v0.6.3
+ github.com/gotk3/gotk3 v0.6.4
github.com/mdp/qrterminal/v3 v3.2.0
github.com/qydysky/part v0.28.20240617114802
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
require (
github.com/google/uuid v1.6.0
- github.com/qydysky/biliApi v0.0.0-20240621154030-402fd30c5a23
- golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842
+ github.com/qydysky/biliApi v0.0.0-20240707084224-dd146610f462
+ golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8
)
require (
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
- golang.org/x/crypto v0.24.0 // indirect
+ golang.org/x/crypto v0.25.0 // indirect
golang.org/x/sync v0.7.0 // indirect
- golang.org/x/term v0.21.0 // indirect
+ golang.org/x/term v0.22.0 // indirect
modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect
- modernc.org/libc v1.53.3 // indirect
+ modernc.org/libc v1.54.2 // indirect
modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.8.0 // indirect
modernc.org/strutil v1.2.0 // indirect
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.8.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
- golang.org/x/mod v0.18.0 // indirect
- golang.org/x/net v0.26.0 // indirect
- golang.org/x/sys v0.21.0 // indirect
+ golang.org/x/mod v0.19.0 // indirect
+ golang.org/x/net v0.27.0 // indirect
+ golang.org/x/sys v0.22.0 // indirect
golang.org/x/tools v0.22.0 // indirect
modernc.org/sqlite v1.30.1
rsc.io/qr v0.2.0 // indirect
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
-github.com/gotk3/gotk3 v0.6.3 h1:+Ke4WkM1TQUNOlM2TZH6szqknqo+zNbX3BZWVXjSHYw=
-github.com/gotk3/gotk3 v0.6.3/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q=
+github.com/gotk3/gotk3 v0.6.4 h1:5ur/PRr86PwCG8eSj98D1eXvhrNNK6GILS2zq779dCg=
+github.com/gotk3/gotk3 v0.6.4/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/qydysky/biliApi v0.0.0-20240621154030-402fd30c5a23 h1:xMqDxMA6K4CAFqwenaSlSJjJ7xSAtFmpojpkO7latMM=
-github.com/qydysky/biliApi v0.0.0-20240621154030-402fd30c5a23/go.mod h1:om024vfxALQ5vxsbaGoMm8IS0esLYBnEOpJI8FsGoDg=
+github.com/qydysky/biliApi v0.0.0-20240707084224-dd146610f462 h1:SblV/m+0mx6QgH2YYvdjE5QxhyfE/EOQglJ1PGd3x3E=
+github.com/qydysky/biliApi v0.0.0-20240707084224-dd146610f462/go.mod h1:om024vfxALQ5vxsbaGoMm8IS0esLYBnEOpJI8FsGoDg=
github.com/qydysky/part v0.28.20240617114802 h1:cmDWin7303nKFQ7HAL2+Ur87vkh8d67xVqudvpXp96E=
github.com/qydysky/part v0.28.20240617114802/go.mod h1:dgagZnPYRFZDbt7XJf7nADOJLoYwlebD9B8Z8g5aHhI=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
-golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
-golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
-golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
-golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
-golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
-golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
-golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
-golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
+golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
+golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
+golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
+golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
+golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
+golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
+golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
-golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
-golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
+golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
+golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
+golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-modernc.org/cc/v4 v4.21.3 h1:2mhBdWKtivdFlLR1ecKXTljPG1mfvbByX7QKztAIJl8=
-modernc.org/cc/v4 v4.21.3/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
-modernc.org/ccgo/v4 v4.18.1 h1:1zF5kPBFq/ZVTulBOKgQPQITdOzzyBUfC51gVYP62E4=
-modernc.org/ccgo/v4 v4.18.1/go.mod h1:ao1fAxf9a2KEOL15WY8+yP3wnpaOpP/QuyFOZ9HJolM=
+modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ=
+modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
+modernc.org/ccgo/v4 v4.19.0 h1:f9K5VdC0nVhHKTFMvhjtZ8TbRgFQbASvE5yO1zs8eC0=
+modernc.org/ccgo/v4 v4.19.0/go.mod h1:CfpAl+673iXNwMG/aqcQn+vDcu4Es/YLya7+9RHjTa4=
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw=
modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU=
modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b h1:BnN1t+pb1cy61zbvSUV7SeI0PwosMhlAEi/vBY4qxp8=
modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
-modernc.org/libc v1.53.3 h1:9O0aSLZuHPgp49we24NoFFteRgXNLGBAQ3TODrW3XLg=
-modernc.org/libc v1.53.3/go.mod h1:kb+Erju4FfHNE59xd2fNpv5CBeAeej6fHbx8p8xaiyI=
+modernc.org/libc v1.54.2 h1:9ymAodb+3v85YfBIZqn62BGgO4L9zF2Hx4LNb6dSU/Q=
+modernc.org/libc v1.54.2/go.mod h1:B0D6klDmSmnq26T1iocn9kzyX6NtbzjuI3+oX/xfvng=
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=