From f64b235415f53dc392ba5dc4391010aca1ff141b Mon Sep 17 00:00:00 2001 From: qydysky Date: Sun, 7 Jul 2024 08:55:45 +0000 Subject: [PATCH] =?utf8?q?Add=20=E9=85=8D=E7=BD=AE=E9=A1=B9=20=E6=9C=8D?= =?utf8?q?=E5=8A=A1=E5=99=A8=E6=97=B6=E5=8C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- CV/Var.go | 6 + F/CookieCrypo.go | 16 ++- F/api.go | 269 ++++++++++++++++++------------------ F/biliApiInterface.go | 1 + Reply/gtk.go | 2 +- bili_danmu.go | 95 +++++++------ cmd/cmd.go | 16 +-- demo/config/config_K_v.json | 4 +- go.mod | 18 +-- go.sum | 44 +++--- 10 files changed, 243 insertions(+), 228 deletions(-) diff --git a/CV/Var.go b/CV/Var.go index 438abd4..9ac13f0 100644 --- a/CV/Var.go +++ b/CV/Var.go @@ -71,6 +71,7 @@ type Common struct { 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"` //当前直播流类型 @@ -183,6 +184,7 @@ func (t *Common) Copy() *Common { 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, @@ -485,6 +487,10 @@ func (t *Common) Init() *Common { 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 { diff --git a/F/CookieCrypo.go b/F/CookieCrypo.go index 2179c03..7a154b0 100644 --- a/F/CookieCrypo.go +++ b/F/CookieCrypo.go @@ -2,6 +2,7 @@ package F import ( "fmt" + "sync" c "github.com/qydysky/bili_danmu/CV" crypto "github.com/qydysky/part/crypto" @@ -10,13 +11,18 @@ import ( // 公私钥加密 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 { @@ -78,6 +84,10 @@ func CookieGet() []byte { 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 { diff --git a/F/api.go b/F/api.go index 800bfad..aa284e3 100644 --- a/F/api.go +++ b/F/api.go @@ -38,6 +38,7 @@ 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 { + ba.SetLocation(c.C.SerLocation) ba.SetProxy(c.C.Proxy) ba.SetReqPool(c.C.ReqPool) return ba @@ -58,11 +59,11 @@ func Get(c *c.Common) *GetFunc { 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`) @@ -76,158 +77,158 @@ func (c *GetFunc) Get(key string) { 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 @@ -244,31 +245,31 @@ func (c *GetFunc) Get(key string) { 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) @@ -277,27 +278,27 @@ func (c *GetFunc) Get(key string) { } 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 } @@ -486,78 +487,78 @@ func (t *GetFunc) configStreamType(sts []struct { } } -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 } @@ -749,11 +750,11 @@ func (t *GetFunc) getRoomPlayInfoByQn() (missKey []string) { 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 { @@ -761,12 +762,12 @@ func (c *GetFunc) getDanmuInfo() (missKey []string) { } //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 } @@ -1045,7 +1046,7 @@ func (t *GetFunc) Get_cookie() (missKey []string) { } // 获取其他Cookie -// func (c *GetFunc) Get_other_cookie() { +// func (t *GetFunc) Get_other_cookie() { // apilog := apilog.Base_add(`获取其他Cookie`) // r := c.ReqPool.Get() @@ -1133,12 +1134,12 @@ func Get_weared_medal(uid, upUid int) (item J.GetWearedMedal_Data) { 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 { @@ -1157,15 +1158,15 @@ func (c *GetFunc) CheckSwitch_FansMedal() (missKey []string) { } 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 } } @@ -1173,16 +1174,16 @@ func (c *GetFunc) CheckSwitch_FansMedal() (missKey []string) { 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 } } @@ -1196,7 +1197,7 @@ func (c *GetFunc) CheckSwitch_FansMedal() (missKey []string) { } else { apilog.L(`I: `, `自动切换粉丝牌 id:`, medal_id) } - c.Wearing_FansMedal = medal_id //更新佩戴信息 + t.Wearing_FansMedal = medal_id //更新佩戴信息 return } } @@ -1539,7 +1540,7 @@ func GetHistory(Roomid_int int) (j []string) { } } -func (c *GetFunc) SearchUP(s string) (list []struct { +func (t *GetFunc) SearchUP(s string) (list []struct { Roomid int Uname string Is_live bool @@ -1582,7 +1583,7 @@ func IsConnected() 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, ".")] diff --git a/F/biliApiInterface.go b/F/biliApiInterface.go index ef51c6b..070e4fb 100644 --- a/F/biliApiInterface.go +++ b/F/biliApiInterface.go @@ -11,6 +11,7 @@ import ( 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) diff --git a/Reply/gtk.go b/Reply/gtk.go index a167b9f..0ef64c9 100644 --- a/Reply/gtk.go +++ b/Reply/gtk.go @@ -344,7 +344,7 @@ func Gtk_danmu() { 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")) diff --git a/bili_danmu.go b/bili_danmu.go index dd1a7e5..2026f82 100644 --- a/bili_danmu.go +++ b/bili_danmu.go @@ -167,19 +167,22 @@ func Start() { } 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 { @@ -194,39 +197,31 @@ func Start() { //附加功能 自动发送即将过期礼物 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{ @@ -260,7 +255,7 @@ func Start() { // 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) { @@ -278,17 +273,24 @@ func Start() { } } - 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) { @@ -309,9 +311,9 @@ func Start() { }() // 刷新舰长数 - 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`, @@ -324,18 +326,18 @@ func Start() { { //附加功能 进房间发送弹幕 直播流保存 每日签到 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 @@ -346,39 +348,40 @@ func Start() { }, `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 { //日期更换 @@ -386,7 +389,7 @@ func Start() { //每日签到 F.Dosign() //每日兑换硬币 - F.Get(c.C).Silver_2_coin() + F.Get(common).Silver_2_coin() //附加功能 每日发送弹幕 reply.Entry_danmu() //附加功能 保持牌子点亮 diff --git a/cmd/cmd.go b/cmd/cmd.go index aae26ae..7c2e557 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -102,7 +102,7 @@ func Cmd() { 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) @@ -191,16 +191,8 @@ func Cmd() { } 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)) @@ -227,7 +219,7 @@ func Cmd() { 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+")") diff --git a/demo/config/config_K_v.json b/demo/config/config_K_v.json index bad780d..ac5b2a5 100644 --- a/demo/config/config_K_v.json +++ b/demo/config/config_K_v.json @@ -200,5 +200,7 @@ "生成pgo-help":"将在退出后生成pgo文件在指定路径,default.pgo将有助于下次构建的优化,但会导致gc频繁,构建缓慢,为空时不生成", "生成pgo":"", "登陆二维码-白":"OO", - "登陆二维码-黑":" " + "登陆二维码-黑":" ", + "服务器时区-help":"用于正确解析服务器响应中的时间,整数,单位秒,整数是UTC以东,默认0", + "服务器时区":0 } \ No newline at end of file diff --git a/go.mod b/go.mod index b0bd66f..463ac64 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/qydysky/bili_danmu 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 @@ -13,8 +13,8 @@ require ( 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 ( @@ -26,11 +26,11 @@ 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 @@ -52,9 +52,9 @@ require ( 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 diff --git a/go.sum b/go.sum index cba6b00..af13ec3 100644 --- a/go.sum +++ b/go.sum @@ -18,8 +18,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 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= @@ -44,8 +44,8 @@ github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdh 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= @@ -69,23 +69,23 @@ github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYg 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= @@ -94,18 +94,18 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 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= -- 2.39.2