From 15c54bee10df690fd26bee8396d84e709600d4d0 Mon Sep 17 00:00:00 2001 From: qydysky Date: Sun, 10 Apr 2022 18:35:13 +0800 Subject: [PATCH] refactor --- CV/Var.go | 206 +++++++---------- F/CookieCrypo.go | 56 ++--- F/F.go | 63 +++--- F/api.go | 84 +++---- F/cmd.go | 66 +++--- F/xinxin.go | 195 ++++++++-------- Reply/F.go | 160 +++++++------- Reply/Msg.go | 2 +- Reply/Reply.go | 96 ++++---- Reply/flvDecode.go | 502 ++++++++++++++++++++++-------------------- Reply/steam/stream.go | 12 +- Reply/tts.go | 30 +-- Send/Send.go | 73 +++--- Send/Send_gift.go | 120 +++++----- Send/Send_pm.go | 85 +++---- bili_danmu.go | 219 +++++++++--------- 16 files changed, 995 insertions(+), 974 deletions(-) diff --git a/CV/Var.go b/CV/Var.go index ddd383b..a103c82 100644 --- a/CV/Var.go +++ b/CV/Var.go @@ -11,134 +11,39 @@ import ( ) type Common struct { - Uid int //client uid - Live []string //直播流链接 - Live_qn int //当前直播流质量 - Live_want_qn int //期望直播流质量 - Roomid int //房间ID - Cookie syncmap.Map //Cookie - Title string //直播标题 - Uname string //主播名 - UpUid int //主播uid - Rev float64 //营收 - Renqi int //人气 - GuardNum int //舰长数 - ParentAreaID int //父分区 - AreaID int //子分区 - Locked bool //直播间封禁 - Note string //分区排行 - Live_Start_Time time.Time //直播开始时间 - Liveing bool //是否在直播 - Wearing_FansMedal int //当前佩戴的粉丝牌 - Token string //弹幕钥 - WSURL []string //弹幕链接 - LIVE_BUVID bool //cookies含LIVE_BUVID - Stream_url string //直播Web服务 - Proxy string //全局代理 - AcceptQn map[int]string //允许的直播流质量 - Qn map[int]string //全部直播流质量 - K_v syncmap.Map //配置文件 + Uid int //client uid + Live []string //直播流链接 + Live_qn int //当前直播流质量 + Live_want_qn int //期望直播流质量 + Roomid int //房间ID + Cookie syncmap.Map //Cookie + Title string //直播标题 + Uname string //主播名 + UpUid int //主播uid + Rev float64 //营收 + Renqi int //人气 + GuardNum int //舰长数 + ParentAreaID int //父分区 + AreaID int //子分区 + Locked bool //直播间封禁 + Note string //分区排行 + Live_Start_Time time.Time //直播开始时间 + Liveing bool //是否在直播 + Wearing_FansMedal int //当前佩戴的粉丝牌 + Token string //弹幕钥 + WSURL []string //弹幕链接 + LIVE_BUVID bool //cookies含LIVE_BUVID + Stream_url string //直播Web服务 + Proxy string //全局代理 + AcceptQn map[int]string //允许的直播流质量 + Qn map[int]string //全部直播流质量 + K_v syncmap.Map //配置文件 + Log *log.Log_interface //日志 + Danmu_Main_mq *mq.Msgq //消息 } -var ( - Uid = 0 //client uid - - Live []string //直播流链接 - Live_qn int //当前直播流质量 - Live_want_qn int //期望直播流质量 - Roomid int - Cookie syncmap.Map - Title string //直播标题 - Uname string //主播名 - UpUid int //主播uid - Rev float64 //营收 - Renqi int //人气 - GuardNum int //舰长数 - ParentAreaID int //父分区 - AreaID int //子分区 - Locked bool //直播间封禁 - Note string //分区排行 - Live_Start_Time time.Time //直播开始时间 - Liveing bool //是否在直播 - Wearing_FansMedal int //当前佩戴的粉丝牌 - Token string //弹幕钥 - WSURL []string //弹幕链接 - LIVE_BUVID bool //cookies含LIVE_BUVID -) - -var ( - Stream_url string //直播Web服务 -) - -//消息队列 -type Danmu_Main_mq_item struct { - Class string - Data interface{} -} - -//200长度防止push击穿 -var Danmu_Main_mq = mq.New(200) - -//k-v -var K_v syncmap.Map - -func init() { - bb, err := ioutil.ReadFile("config/config_K_v.json") - if err != nil { - return - } - var data map[string]interface{} - json.Unmarshal(bb, &data) - for k, v := range data { - K_v.Store(k, v) - } -} - -//constKv -var ( - Proxy string //全局代理 -) - -func init() { - Proxy, _ = K_v.LoadV("http代理地址").(string) -} - -//日志 -var Log = log.New(log.Config{ - File: `danmu.log`, - Stdout: true, - Prefix_string: map[string]struct{}{ - `T: `: log.On, - `I: `: log.On, - `N: `: log.On, - `W: `: log.On, - `E: `: log.On, - }, -}) - -func init() { - logmap := make(map[string]struct{}) - if array, ok := K_v.Load(`日志显示`); ok { - for _, v := range array.([]interface{}) { - logmap[v.(string)] = log.On - } - } - Log = Log.Level(logmap) - return -} - -//from player-loader-2.0.11.min.js -/* - customAuthParam -*/ -// var ( -// VERSION = "2.0.11" -// ) // 不再需要 - -//允许的清晰度 - -var ( - AcceptQn = map[int]string{ +func (t *Common) init() Common { + t.Qn = map[int]string{ // no change 10000: "原画", 800: "4K", 401: "蓝光(杜比)", @@ -147,7 +52,8 @@ var ( 150: "高清", 80: "流畅", } - Qn = map[int]string{ // no change + + t.AcceptQn = map[int]string{ // no change 10000: "原画", 800: "4K", 401: "蓝光(杜比)", @@ -156,4 +62,48 @@ var ( 150: "高清", 80: "流畅", } -) + + t.Log = log.New(log.Config{ + File: `danmu.log`, + Stdout: true, + Prefix_string: map[string]struct{}{ + `T: `: log.On, + `I: `: log.On, + `N: `: log.On, + `W: `: log.On, + `E: `: log.On, + }, + }) + + t.Danmu_Main_mq = mq.New(200) + + if bb, err := ioutil.ReadFile("config/config_K_v.json"); err == nil { + var data map[string]interface{} + json.Unmarshal(bb, &data) + for k, v := range data { + t.K_v.Store(k, v) + } + } + + if val, exist := t.K_v.Load("http代理地址"); exist { + t.Proxy = val.(string) + } + + logmap := make(map[string]struct{}) + if array, ok := t.K_v.Load(`日志显示`); ok { + for _, v := range array.([]interface{}) { + logmap[v.(string)] = log.On + } + } + t.Log = t.Log.Level(logmap) + + return *t +} + +var C = new(Common).init() + +//消息队列 +type Danmu_Main_mq_item struct { + Class string + Data interface{} +} diff --git a/F/CookieCrypo.go b/F/CookieCrypo.go index 4697bea..d9715a3 100644 --- a/F/CookieCrypo.go +++ b/F/CookieCrypo.go @@ -2,31 +2,31 @@ package F import ( "fmt" + c "github.com/qydysky/bili_danmu/CV" p "github.com/qydysky/part" crypto "github.com/qydysky/part/crypto" ) - //公私钥加密 var ( - clog = c.Log.Base(`cookie加密`) - pub []byte - pri []byte + clog = c.C.Log.Base(`cookie加密`) + pub []byte + pri []byte ) -func CookieGet() ([]byte) { +func CookieGet() []byte { clog := clog.Base_add(`获取`) if len(pri) == 0 { - if priS,ok := c.K_v.LoadV(`cookie解密私钥`).(string);ok && priS != ``{ - if d,e := crypto.FileLoad(priS);e != nil { - clog.L(`E: `,e) + if priS, ok := c.C.K_v.LoadV(`cookie解密私钥`).(string); ok && priS != `` { + if d, e := crypto.FileLoad(priS); e != nil { + clog.L(`E: `, e) return []byte{} } else { pri = d } - } else if pubS,ok := c.K_v.LoadV(`cookie加密公钥`).(string);ok && pubS != ``{ - c.Log.Block(1000)//等待所有日志输出完毕 + } else if pubS, ok := c.C.K_v.LoadV(`cookie加密公钥`).(string); ok && pubS != `` { + c.C.Log.Block(1000) //等待所有日志输出完毕 priS := `` fmt.Printf("cookie密钥路径: ") _, err := fmt.Scanln(&priS) @@ -34,14 +34,14 @@ func CookieGet() ([]byte) { clog.L(`E: `, "输入错误", err) return []byte{} } - if d,e := crypto.FileLoad(priS);e != nil { - clog.L(`E: `,e) + if d, e := crypto.FileLoad(priS); e != nil { + clog.L(`E: `, e) return []byte{} } else { pri = d } } else { - if d,e := crypto.FileLoad(`cookie.txt`);e != nil || string(d[:3]) != `nol` { + if d, e := crypto.FileLoad(`cookie.txt`); e != nil || string(d[:3]) != `nol` { clog.L(`E: `, e, `cookie保存格式:`, string(d[:3])) return []byte{} } else { @@ -49,11 +49,11 @@ func CookieGet() ([]byte) { } } } - if source,e := crypto.FileLoad(`cookie.txt`);e != nil || string(source[:3]) != `pem` { + if source, e := crypto.FileLoad(`cookie.txt`); e != nil || string(source[:3]) != `pem` { clog.L(`E: `, e, `cookie保存格式:`, string(source[:3])) return []byte{} - } else if s,e := crypto.Decrypt(source[3:],pri);e != nil{ - clog.L(`E: `,e) + } else if s, e := crypto.Decrypt(source[3:], pri); e != nil { + clog.L(`E: `, e) return []byte{} } else { return s @@ -63,9 +63,9 @@ func CookieGet() ([]byte) { func CookieSet(source []byte) { clog := clog.Base_add(`设置`) if len(pub) == 0 { - if pubS,ok := c.K_v.LoadV(`cookie加密公钥`).(string);ok && pubS != ``{ - if d,e := crypto.FileLoad(pubS);e != nil { - clog.L(`E: `,e) + if pubS, ok := c.C.K_v.LoadV(`cookie加密公钥`).(string); ok && pubS != `` { + if d, e := crypto.FileLoad(pubS); e != nil { + clog.L(`E: `, e) return } else { pub = d @@ -73,22 +73,22 @@ func CookieSet(source []byte) { } else { f := p.File() f.FileWR(p.Filel{ - File:`cookie.txt`, - Loc:0, - Context:[]interface{}{`nol`,source}, + File: `cookie.txt`, + Loc: 0, + Context: []interface{}{`nol`, source}, }) return } } - if source,e := crypto.Encrypt(source,pub);e != nil{ - clog.L(`E: `,e) + if source, e := crypto.Encrypt(source, pub); e != nil { + clog.L(`E: `, e) return } else { f := p.File() f.FileWR(p.Filel{ - File:`cookie.txt`, - Loc:0, - Context:[]interface{}{`pem`,source}, + File: `cookie.txt`, + Loc: 0, + Context: []interface{}{`pem`, source}, }) } -} \ No newline at end of file +} diff --git a/F/F.go b/F/F.go index 1b08e00..aaae406 100644 --- a/F/F.go +++ b/F/F.go @@ -7,7 +7,7 @@ import ( c "github.com/qydysky/bili_danmu/CV" ) -var flog = c.Log.Base(`F/F.go`) +var flog = c.C.Log.Base(`F/F.go`) //base on source/player-loader-2.0.7.min.js L3313 //base on source/player-loader-2.0.7.min.js L3455 @@ -20,7 +20,7 @@ type header struct { } //头部生成与检查 -func HeadGen(datalenght,Opeation,Sequence int) []byte { +func HeadGen(datalenght, Opeation, Sequence int) []byte { var buffer bytes.Buffer //Buffer是一个实现了读写方法的可变大小的字节缓冲 buffer.Write(Itob32(int32(datalenght + c.WS_PACKAGE_HEADER_TOTAL_LENGTH))) @@ -32,9 +32,12 @@ func HeadGen(datalenght,Opeation,Sequence int) []byte { return buffer.Bytes() } -func HeadChe(head []byte) (header) { +func HeadChe(head []byte) header { - if len(head) != c.WS_PACKAGE_HEADER_TOTAL_LENGTH {flog.Base_add("头部检查").L(`E: `,"输入头长度错误");return header{}} + if len(head) != c.WS_PACKAGE_HEADER_TOTAL_LENGTH { + flog.Base_add("头部检查").L(`E: `, "输入头长度错误") + return header{} + } PackL := Btoi32(head, c.WS_PACKAGE_OFFSET) HeadL := Btoi16(head, c.WS_HEADER_OFFSET) @@ -43,11 +46,11 @@ func HeadChe(head []byte) (header) { Seque := Btoi32(head, c.WS_SEQUENCE_OFFSET) return header{ - PackL :PackL, - HeadL :HeadL, - BodyV :BodyV, - OpeaT :OpeaT, - Seque :Seque, + PackL: PackL, + HeadL: HeadL, + BodyV: BodyV, + OpeaT: OpeaT, + Seque: Seque, } } @@ -56,20 +59,20 @@ func HelloGen(roomid int, key string) []byte { flog := flog.Base_add("认证生成") if roomid == 0 || key == "" { - flog.L(`E: `,"roomid == 0 || key == \"\"") + flog.L(`E: `, "roomid == 0 || key == \"\"") return []byte("") } - var obj = `{"uid":` + strconv.Itoa(c.Uid) + - `,"roomid":` + strconv.Itoa(roomid) + - `,"protover":` + strconv.Itoa(c.Protover) + - `,"platform":"`+ c.Platform + - // `","clientver":"` + c.VERSION + //delete at 2021 4 14 - `","type":` + strconv.Itoa(c.Type) + - `,"key":"` + key + `"}` + var obj = `{"uid":` + strconv.Itoa(c.C.Uid) + + `,"roomid":` + strconv.Itoa(roomid) + + `,"protover":` + strconv.Itoa(c.Protover) + + `,"platform":"` + c.Platform + + // `","clientver":"` + c.VERSION + //delete at 2021 4 14 + `","type":` + strconv.Itoa(c.Type) + + `,"key":"` + key + `"}` var buffer bytes.Buffer //Buffer是一个实现了读写方法的可变大小的字节缓冲 - + buffer.Write(HeadGen(len(obj), c.WS_OP_USER_AUTHENTICATION, c.WS_HEADER_DEFAULT_SEQUENCE)) buffer.Write([]byte(obj)) @@ -78,7 +81,9 @@ func HelloGen(roomid int, key string) []byte { } func HelloChe(r []byte) bool { - if len(r) == 0 {return false} + if len(r) == 0 { + return false + } var obj = `{"code":0}` @@ -90,10 +95,14 @@ func HelloChe(r []byte) bool { h := buffer.Bytes() - if len(h) != len(r) {return false} + if len(h) != len(r) { + return false + } for k, v := range r { - if v != h[k] {return false} + if v != h[k] { + return false + } } return true } @@ -106,7 +115,7 @@ func Heartbeat() ([]byte, int) { var obj = `[object Object]` var buffer bytes.Buffer //Buffer是一个实现了读写方法的可变大小的字节缓冲 - + buffer.Write(HeadGen(len(obj), c.WS_OP_HEARTBEAT, c.WS_HEADER_DEFAULT_SEQUENCE)) buffer.Write([]byte(obj)) @@ -117,11 +126,13 @@ func Heartbeat() ([]byte, int) { //cookie检查 func CookieCheck(key []string) (missKey []string) { - for _,tk := range key{ - if tk == `` {continue} - if _,ok := c.Cookie.Load(tk);!ok{ + for _, tk := range key { + if tk == `` { + continue + } + if _, ok := c.C.Cookie.Load(tk); !ok { missKey = append(missKey, tk) } } return -} \ No newline at end of file +} diff --git a/F/api.go b/F/api.go index 3257eec..0f5a005 100644 --- a/F/api.go +++ b/F/api.go @@ -26,11 +26,15 @@ import ( qr "github.com/skip2/go-qrcode" ) -var apilog = c.Log.Base(`api`) +var apilog = c.C.Log.Base(`api`) var api_limit = limit.New(1, 2000, 30000) //频率限制1次/2s,最大等待时间30s type GetFunc struct { - c.Common + *c.Common +} + +func Get(c *c.Common) *GetFunc { + return &GetFunc{c} } func (c *GetFunc) Get(key string) { @@ -893,7 +897,7 @@ func Get_face_src(uid string) string { apilog := apilog.Base_add(`获取头像`) Cookie := make(map[string]string) - c.Cookie.Range(func(k, v interface{}) bool { + c.C.Cookie.Range(func(k, v interface{}) bool { Cookie[k.(string)] = v.(string) return true }) @@ -902,10 +906,10 @@ func Get_face_src(uid string) string { if err := req.Reqf(reqf.Rval{ Url: "https://api.live.bilibili.com/xlive/web-room/v1/index/getDanmuMedalAnchorInfo?ruid=" + uid, Header: map[string]string{ - `Referer`: "https://live.bilibili.com/" + strconv.Itoa(c.Roomid), + `Referer`: "https://live.bilibili.com/" + strconv.Itoa(c.C.Roomid), `Cookie`: reqf.Map_2_Cookies_String(Cookie), }, - Proxy: c.Proxy, + Proxy: c.C.Proxy, Timeout: 10 * 1000, Retry: 2, }); err != nil { @@ -1142,7 +1146,7 @@ func Info(UpUid int) (info J.Info) { req := reqf.New() if err := req.Reqf(reqf.Rval{ Url: `https://api.bilibili.com/x/space/acc/info?mid=` + strconv.Itoa(UpUid) + `&jsonp=jsonp`, - Proxy: c.Proxy, + Proxy: c.C.Proxy, Timeout: 10 * 1000, Retry: 2, }); err != nil { @@ -1417,7 +1421,7 @@ func Get_list_in_room() (array []J.GetMyMedals_Items) { return } Cookie := make(map[string]string) - c.Cookie.Range(func(k, v interface{}) bool { + c.C.Cookie.Range(func(k, v interface{}) bool { Cookie[k.(string)] = v.(string) return true }) @@ -1431,7 +1435,7 @@ func Get_list_in_room() (array []J.GetMyMedals_Items) { Header: map[string]string{ `Cookie`: reqf.Map_2_Cookies_String(Cookie), }, - Proxy: c.Proxy, + Proxy: c.C.Proxy, Timeout: 10 * 1000, Retry: 2, }); e != nil { @@ -1477,7 +1481,7 @@ func Get_weared_medal() (item J.GetWearedMedal_Data) { return } Cookie := make(map[string]string) - c.Cookie.Range(func(k, v interface{}) bool { + c.C.Cookie.Range(func(k, v interface{}) bool { Cookie[k.(string)] = v.(string) return true }) @@ -1489,7 +1493,7 @@ func Get_weared_medal() (item J.GetWearedMedal_Data) { Header: map[string]string{ `Cookie`: reqf.Map_2_Cookies_String(Cookie), }, - Proxy: c.Proxy, + Proxy: c.C.Proxy, Timeout: 10 * 1000, Retry: 2, }); e != nil { @@ -1640,7 +1644,7 @@ func Dosign() { { //检查是否签到 Cookie := make(map[string]string) - c.Cookie.Range(func(k, v interface{}) bool { + c.C.Cookie.Range(func(k, v interface{}) bool { Cookie[k.(string)] = v.(string) return true }) @@ -1661,7 +1665,7 @@ func Dosign() { `Referer`: "https://live.bilibili.com/all", `Cookie`: reqf.Map_2_Cookies_String(Cookie), }, - Proxy: c.Proxy, + Proxy: c.C.Proxy, Timeout: 3 * 1000, Retry: 2, }); err != nil { @@ -1690,7 +1694,7 @@ func Dosign() { { //签到 Cookie := make(map[string]string) - c.Cookie.Range(func(k, v interface{}) bool { + c.C.Cookie.Range(func(k, v interface{}) bool { Cookie[k.(string)] = v.(string) return true }) @@ -1711,7 +1715,7 @@ func Dosign() { `Referer`: "https://live.bilibili.com/all", `Cookie`: reqf.Map_2_Cookies_String(Cookie), }, - Proxy: c.Proxy, + Proxy: c.C.Proxy, Timeout: 3 * 1000, Retry: 2, }); err != nil { @@ -1833,7 +1837,7 @@ func F_x25Kn_cancel() { func F_x25Kn() { apilog := apilog.Base_add(`小心心`) - if c.Wearing_FansMedal == 0 { + if c.C.Wearing_FansMedal == 0 { apilog.L(`I: `, `无粉丝牌,不获取`) return } @@ -1846,11 +1850,11 @@ func F_x25Kn() { apilog.L(`T: `, `Cookie无Key:`, missKey) return } - if c.ParentAreaID == -1 { + if c.C.ParentAreaID == -1 { apilog.L(`E: `, `失败!未获取Parent_area_id`) return } - if c.AreaID == -1 { + if c.C.AreaID == -1 { apilog.L(`E: `, `失败!未获取Area_id`) return } @@ -1884,13 +1888,13 @@ func F_x25Kn() { loop_num = 0 ) - csrf, _ := c.Cookie.LoadV(`bili_jct`).(string) + csrf, _ := c.C.Cookie.LoadV(`bili_jct`).(string) if csrf == `` { apilog.L(`E: `, "Cookie错误,无bili_jct") return } - LIVE_BUVID := c.Cookie.LoadV(`LIVE_BUVID`).(string) + LIVE_BUVID := c.C.Cookie.LoadV(`LIVE_BUVID`).(string) if LIVE_BUVID == `` { apilog.L(`E: `, "Cookie错误,无LIVE_BUVID") return @@ -1908,7 +1912,7 @@ func F_x25Kn() { { //初始化 - PostStr := `id=[` + strconv.Itoa(c.ParentAreaID) + `,` + strconv.Itoa(c.AreaID) + `,` + strconv.Itoa(loop_num) + `,` + strconv.Itoa(c.Roomid) + `]&` + PostStr := `id=[` + strconv.Itoa(c.C.ParentAreaID) + `,` + strconv.Itoa(c.C.AreaID) + `,` + strconv.Itoa(loop_num) + `,` + strconv.Itoa(c.C.Roomid) + `]&` PostStr += `device=["` + LIVE_BUVID + `","` + new_uuid + `"]&` PostStr += `ts=` + strconv.Itoa(int(p.Sys().GetMTime())) PostStr += `&is_patch=0&` @@ -1918,7 +1922,7 @@ func F_x25Kn() { PostStr += `visit_id=` Cookie := make(map[string]string) - c.Cookie.Range(func(k, v interface{}) bool { + c.C.Cookie.Range(func(k, v interface{}) bool { Cookie[k.(string)] = v.(string) return true }) @@ -1943,11 +1947,11 @@ func F_x25Kn() { `Connection`: `keep-alive`, `Pragma`: `no-cache`, `Cache-Control`: `no-cache`, - `Referer`: "https://live.bilibili.com/" + strconv.Itoa(c.Roomid), + `Referer`: "https://live.bilibili.com/" + strconv.Itoa(c.C.Roomid), `Cookie`: reqf.Map_2_Cookies_String(Cookie), }, PostStr: url.PathEscape(PostStr), - Proxy: c.Proxy, + Proxy: c.C.Proxy, Timeout: 5 * 1000, Retry: 2, }); err != nil { @@ -2005,7 +2009,7 @@ func F_x25Kn() { var ( rt_obj = RT{ R: R{ - Id: `[` + strconv.Itoa(c.ParentAreaID) + `,` + strconv.Itoa(c.AreaID) + `,` + strconv.Itoa(loop_num) + `,` + strconv.Itoa(c.Roomid) + `]`, + Id: `[` + strconv.Itoa(c.C.ParentAreaID) + `,` + strconv.Itoa(c.C.AreaID) + `,` + strconv.Itoa(loop_num) + `,` + strconv.Itoa(c.C.Roomid) + `]`, Device: `["` + LIVE_BUVID + `","` + new_uuid + `"]`, Ets: res.Data.Timestamp, Benchmark: res.Data.Secret_key, @@ -2037,7 +2041,7 @@ func F_x25Kn() { PostStr = `s=` + wasm + `&` + PostStr Cookie := make(map[string]string) - c.Cookie.Range(func(k, v interface{}) bool { + c.C.Cookie.Range(func(k, v interface{}) bool { Cookie[k.(string)] = v.(string) return true }) @@ -2056,11 +2060,11 @@ func F_x25Kn() { `Connection`: `keep-alive`, `Pragma`: `no-cache`, `Cache-Control`: `no-cache`, - `Referer`: "https://live.bilibili.com/" + strconv.Itoa(c.Roomid), + `Referer`: "https://live.bilibili.com/" + strconv.Itoa(c.C.Roomid), `Cookie`: reqf.Map_2_Cookies_String(Cookie), }, PostStr: url.PathEscape(PostStr), - Proxy: c.Proxy, + Proxy: c.C.Proxy, Timeout: 5 * 1000, Retry: 2, }); err != nil { @@ -2116,7 +2120,7 @@ func Gift_list() (list []Gift_list_type_Data_List) { apilog.L(`T: `, `Cookie无Key:`, missKey) return } - if c.Roomid == 0 { + if c.C.Roomid == 0 { apilog.L(`E: `, `失败!无Roomid`) return } @@ -2126,14 +2130,14 @@ func Gift_list() (list []Gift_list_type_Data_List) { } //超额请求阻塞,超时将取消 Cookie := make(map[string]string) - c.Cookie.Range(func(k, v interface{}) bool { + c.C.Cookie.Range(func(k, v interface{}) bool { Cookie[k.(string)] = v.(string) return true }) req := reqf.New() if err := req.Reqf(reqf.Rval{ - Url: `https://api.live.bilibili.com/xlive/web-room/v1/gift/bag_list?t=` + strconv.Itoa(int(p.Sys().GetMTime())) + `&room_id=` + strconv.Itoa(c.Roomid), + Url: `https://api.live.bilibili.com/xlive/web-room/v1/gift/bag_list?t=` + strconv.Itoa(int(p.Sys().GetMTime())) + `&room_id=` + strconv.Itoa(c.C.Roomid), Header: map[string]string{ `Host`: `api.live.bilibili.com`, `User-Agent`: `Mozilla/5.0 (X11; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0`, @@ -2144,10 +2148,10 @@ func Gift_list() (list []Gift_list_type_Data_List) { `Connection`: `keep-alive`, `Pragma`: `no-cache`, `Cache-Control`: `no-cache`, - `Referer`: "https://live.bilibili.com/" + strconv.Itoa(c.Roomid), + `Referer`: "https://live.bilibili.com/" + strconv.Itoa(c.C.Roomid), `Cookie`: reqf.Map_2_Cookies_String(Cookie), }, - Proxy: c.Proxy, + Proxy: c.C.Proxy, Timeout: 3 * 1000, Retry: 2, }); err != nil { @@ -2355,11 +2359,11 @@ func (c *GetFunc) Silver_2_coin() (missKey []string) { func save_cookie(Cookies []*http.Cookie) { for k, v := range reqf.Cookies_List_2_Map(Cookies) { - c.Cookie.Store(k, v) + c.C.Cookie.Store(k, v) } Cookie := make(map[string]string) - c.Cookie.Range(func(k, v interface{}) bool { + c.C.Cookie.Range(func(k, v interface{}) bool { Cookie[k.(string)] = v.(string) return true }) @@ -2390,7 +2394,7 @@ func Feed_list() (Uplist []UpItem) { } //超额请求阻塞,超时将取消 Cookie := make(map[string]string) - c.Cookie.Range(func(k, v interface{}) bool { + c.C.Cookie.Range(func(k, v interface{}) bool { Cookie[k.(string)] = v.(string) return true }) @@ -2412,7 +2416,7 @@ func Feed_list() (Uplist []UpItem) { `Referer`: `https://t.bilibili.com/pages/nav/index_new`, `Cookie`: reqf.Map_2_Cookies_String(Cookie), }, - Proxy: c.Proxy, + Proxy: c.C.Proxy, Timeout: 3 * 1000, Retry: 2, }); err != nil { @@ -2464,7 +2468,7 @@ func GetHistory(Roomid_int int) (j J.GetHistory) { Header: map[string]string{ `Referer`: "https://live.bilibili.com/" + Roomid, }, - Proxy: c.Proxy, + Proxy: c.C.Proxy, Timeout: 10 * 1000, Retry: 2, }); err != nil { @@ -2503,7 +2507,7 @@ func SearchUP(s string) (list []searchresult) { req := reqf.New() if err := req.Reqf(reqf.Rval{ Url: "https://api.bilibili.com/x/web-interface/search/type?context=&search_type=live_user&cover_type=user_cover&page=1&order=&category_id=&__refresh__=true&_extra=&highlight=1&single_column=0&keyword=" + url.PathEscape(s), - Proxy: c.Proxy, + Proxy: c.C.Proxy, Timeout: 10 * 1000, Retry: 2, }); err != nil { @@ -2553,7 +2557,7 @@ func KeepConnect() { func IsConnected() bool { apilog := apilog.Base_add(`IsConnected`) - v, ok := c.K_v.LoadV(`网络中断不退出`).(bool) + v, ok := c.C.K_v.LoadV(`网络中断不退出`).(bool) if !ok || !v { return true } @@ -2561,7 +2565,7 @@ func IsConnected() bool { req := reqf.New() if err := req.Reqf(reqf.Rval{ Url: "https://www.bilibili.com", - Proxy: c.Proxy, + Proxy: c.C.Proxy, Timeout: 10 * 1000, JustResponseCode: true, }); err != nil { diff --git a/F/cmd.go b/F/cmd.go index 6167504..3bcf94d 100644 --- a/F/cmd.go +++ b/F/cmd.go @@ -17,15 +17,15 @@ var liveList = make(map[string]int) func Cmd() { - cmdlog := c.Log.Base_add(`命令行操作`).L(`T: `, `回车查看帮助`) + cmdlog := c.C.Log.Base_add(`命令行操作`).L(`T: `, `回车查看帮助`) scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { if inputs := scanner.Text(); inputs == `` { //帮助 fmt.Print("\n") fmt.Println("切换房间->输入数字回车") - if c.Roomid == 0 { - if _, ok := c.Cookie.LoadV(`bili_jct`).(string); ok { + if c.C.Roomid == 0 { + if _, ok := c.C.Cookie.LoadV(`bili_jct`).(string); ok { fmt.Println("查看直播中主播->输入' live'回车") } else { fmt.Println("登陆->输入' login'回车") @@ -35,7 +35,7 @@ func Cmd() { fmt.Print("\n") continue } - if _, ok := c.Cookie.LoadV(`bili_jct`).(string); ok { + if _, ok := c.C.Cookie.LoadV(`bili_jct`).(string); ok { fmt.Println("发送弹幕->输入' 字符串'回车") fmt.Println("查看直播中主播->输入' live'回车") fmt.Println("获取小心心->输入' getheart'回车") @@ -52,25 +52,25 @@ func Cmd() { cmdlog.L(`W: `, "不支持功能键") } else if inputs[0] == 32 { // 开头 //录制切换 - if strings.Contains(inputs, ` rec`) && c.Roomid != 0 { - if !c.Liveing { + if strings.Contains(inputs, ` rec`) && c.C.Roomid != 0 { + if !c.C.Liveing { cmdlog.L(`W: `, "不能切换录制状态,未在直播") continue } - c.Danmu_Main_mq.Push_tag(`savestream`, nil) + c.C.Danmu_Main_mq.Push_tag(`savestream`, nil) continue } //直播间切换 if strings.Contains(inputs, ` live`) { - if _, ok := c.Cookie.LoadV(`bili_jct`).(string); !ok { + if _, ok := c.C.Cookie.LoadV(`bili_jct`).(string); !ok { cmdlog.L(`W: `, "尚未登陆,未能获取关注主播") continue } fmt.Print("\n") if len(inputs) > 5 { if room, ok := liveList[inputs]; ok { - c.Roomid = room - c.Danmu_Main_mq.Push_tag(`change_room`, nil) + c.C.Roomid = room + c.C.Danmu_Main_mq.Push_tag(`change_room`, nil) continue } cmdlog.L(`W: `, "输入错误", inputs) @@ -86,18 +86,18 @@ func Cmd() { } //登陆 if strings.Contains(inputs, ` login`) { - if _, ok := c.Cookie.LoadV(`bili_jct`).(string); ok { + if _, ok := c.C.Cookie.LoadV(`bili_jct`).(string); ok { cmdlog.L(`W: `, "已登陆") continue } //获取cookie - Get(`Cookie`) + Get(&c.C).Get(`Cookie`) continue } //获取小心心 - if strings.Contains(inputs, ` getheart`) && c.Roomid != 0 { - if _, ok := c.Cookie.LoadV(`bili_jct`).(string); !ok { + if strings.Contains(inputs, ` getheart`) && c.C.Roomid != 0 { + if _, ok := c.C.Cookie.LoadV(`bili_jct`).(string); !ok { cmdlog.L(`W: `, "尚未登陆,不能获取小心心") continue } @@ -128,24 +128,24 @@ func Cmd() { continue } //重载弹幕 - if strings.Contains(inputs, ` reload`) && c.Roomid != 0 { - c.Danmu_Main_mq.Push_tag(`flash_room`, nil) + if strings.Contains(inputs, ` reload`) && c.C.Roomid != 0 { + c.C.Danmu_Main_mq.Push_tag(`flash_room`, nil) continue } //当前直播间信息 - if strings.Contains(inputs, ` room`) && c.Roomid != 0 { + if strings.Contains(inputs, ` room`) && c.C.Roomid != 0 { fmt.Print("\n") fmt.Println("当前直播间信息") { living := `未在直播` - if c.Liveing { + if c.C.Liveing { living = `直播中` } - fmt.Println(c.Uname, c.Title, living) + fmt.Println(c.C.Uname, c.C.Title, living) } { - if c.Liveing { - d := time.Since(c.Live_Start_Time).Round(time.Second) + 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 @@ -155,22 +155,22 @@ func Cmd() { } } { - fmt.Println(`营收:`, fmt.Sprintf("¥%.2f", c.Rev)) + fmt.Println(`营收:`, fmt.Sprintf("¥%.2f", c.C.Rev)) } - fmt.Println(`舰长数:`, c.GuardNum) - fmt.Println(`分区排行:`, c.Note, `人气:`, c.Renqi) - if c.Stream_url != "" { - fmt.Println(`直播Web服务:`, c.Stream_url+`/now`) + fmt.Println(`舰长数:`, c.C.GuardNum) + fmt.Println(`分区排行:`, c.C.Note, `人气:`, c.C.Renqi) + if c.C.Stream_url != "" { + fmt.Println(`直播Web服务:`, c.C.Stream_url+`/now`) } fmt.Print("\n") continue } { //弹幕发送 - if c.Roomid == 0 { + if c.C.Roomid == 0 { continue } - if _, ok := c.Cookie.LoadV(`bili_jct`).(string); !ok { + if _, ok := c.C.Cookie.LoadV(`bili_jct`).(string); !ok { cmdlog.L(`W: `, "尚未登陆,不能发送弹幕") continue } @@ -178,17 +178,17 @@ func Cmd() { cmdlog.L(`W: `, "输入长度过短", inputs) continue } - send.Danmu_s(inputs[1:], c.Roomid) + send.Danmu_s(inputs[1:], c.C.Roomid) } } else if room, err := strconv.Atoi(inputs); err == nil { //直接进入房间 - c.Roomid = room + c.C.Roomid = room cmdlog.L(`I: `, "进入房间", room) - c.Danmu_Main_mq.Push_tag(`change_room`, nil) + c.C.Danmu_Main_mq.Push_tag(`change_room`, nil) } else { //其余字符串 - if c.Roomid == 0 { + if c.C.Roomid == 0 { continue } - send.Danmu_s(inputs, c.Roomid) + send.Danmu_s(inputs, c.C.Roomid) } } } diff --git a/F/xinxin.go b/F/xinxin.go index 2362534..f48fa2a 100644 --- a/F/xinxin.go +++ b/F/xinxin.go @@ -1,19 +1,19 @@ package F import ( + "encoding/json" "net/http" "strconv" - "encoding/json" - "time" "strings" + "time" c "github.com/qydysky/bili_danmu/CV" p "github.com/qydysky/part" - websocket "github.com/qydysky/part/websocket" msgq "github.com/qydysky/part/msgq" - web "github.com/qydysky/part/web" reqf "github.com/qydysky/part/reqf" + web "github.com/qydysky/part/web" + websocket "github.com/qydysky/part/websocket" "github.com/skratchdot/open-golang/open" ) @@ -24,71 +24,72 @@ import ( //需要加密的数据 type R struct { - Id string `json:"id"` - Device string `json:"device"` - Ets int `json:"ets"` + Id string `json:"id"` + Device string `json:"device"` + Ets int `json:"ets"` Benchmark string `json:"benchmark"` - Time int `json:"time"` - Ts int `json:"ts"` - Ua string `json:"ua"` + Time int `json:"time"` + Ts int `json:"ts"` + Ua string `json:"ua"` } //发送的原始对象 type RT struct { - R R `json:"r"` + R R `json:"r"` T []int `json:"t"` //加密方法 } //返回的加密对象 type S struct { - Id string `json:"id"`//发送的数据中的Id项,以确保是对应的返回 - S string `json:"s"` //加密字符串 + Id string `json:"id"` //发送的数据中的Id项,以确保是对应的返回 + S string `json:"s"` //加密字符串 } - //全局对象 var ( - wslog = c.Log.Base(`api`).Base_add(`小心心加密`) //日志 - rec_chan = make(chan S,5)//收通道 - webpath string//web地址,由于实时获取空闲端口,故将在稍后web启动后赋值 - ws = websocket.New_server()//新建websocket实例 + wslog = c.C.Log.Base(`api`).Base_add(`小心心加密`) //日志 + rec_chan = make(chan S, 5) //收通道 + webpath string //web地址,由于实时获取空闲端口,故将在稍后web启动后赋值 + ws = websocket.New_server() //新建websocket实例 nodeJsUrl string ) func init() { go func() { for { - v,ok := c.K_v.Load("get_xiao_xinxin") + v, ok := c.C.K_v.Load("get_xiao_xinxin") if !ok { time.Sleep(time.Second) continue } - if t,ok := v.(bool);!ok || !t {return} + if t, ok := v.(bool); !ok || !t { + return + } break } - + //初始化web服务器,初始化websocket - NodeJsUrl,ok := c.K_v.LoadV("小心心nodjs加密服务地址").(string) + NodeJsUrl, ok := c.C.K_v.LoadV("小心心nodjs加密服务地址").(string) if ok && NodeJsUrl != "" { nodeJsUrl = NodeJsUrl if test(0) { - wslog.L(`I: `,`使用NodeJs`,NodeJsUrl,`进行加密`) + wslog.L(`I: `, `使用NodeJs`, NodeJsUrl, `进行加密`) } else { - wslog.L(`E: `,`发生错误!`) + wslog.L(`E: `, `发生错误!`) } } else { server() } - wslog.L(`T: `,`启动`) + wslog.L(`T: `, `启动`) }() } func server() { { - ws_mq := ws.Interface()//获取websocket操作对象 + ws_mq := ws.Interface() //获取websocket操作对象 ws_mq.Pull_tag(msgq.FuncMap{ - `recv`:func(data interface{})(bool){ - if tmp,ok := data.(websocket.Uinterface);ok {//websocket接收并响应 + `recv`: func(data interface{}) bool { + if tmp, ok := data.(websocket.Uinterface); ok { //websocket接收并响应 //websocket.Uinterface{ // Id uintptr 会话id // Data []byte 接收的websocket数据 @@ -100,7 +101,7 @@ func server() { wslog.L(`E: `, e, string(tmp.Data)) } - select{ + select { case rec_chan <- s: default: } @@ -108,7 +109,7 @@ func server() { } return false }, - `error`:func(data interface{})(bool){//websocket错误 + `error`: func(data interface{}) bool { //websocket错误 wslog.L(`W: `, data) return false }, @@ -116,58 +117,60 @@ func server() { } w := web.New(&http.Server{ - Addr: "127.0.0.1:"+strconv.Itoa(p.Sys().GetFreePort()), - })//新建web实例 - w.Handle(map[string]func(http.ResponseWriter,*http.Request){//路径处理函数 - `/`:func(w http.ResponseWriter,r *http.Request){ + Addr: "127.0.0.1:" + strconv.Itoa(p.Sys().GetFreePort()), + }) //新建web实例 + w.Handle(map[string]func(http.ResponseWriter, *http.Request){ //路径处理函数 + `/`: func(w http.ResponseWriter, r *http.Request) { var path string = r.URL.Path[1:] - if path == `` {path = `index.html`} + if path == `` { + path = `index.html` + } http.ServeFile(w, r, "html/"+path) }, - `/ws`:func(w http.ResponseWriter,r *http.Request){ + `/ws`: func(w http.ResponseWriter, r *http.Request) { //获取通道 - conn := ws.WS(w,r) + conn := ws.WS(w, r) //由通道获取本次会话id,并测试 提示 go test(<-conn) //等待会话结束,通道释放 <-conn }, }) - webpath = `http://`+w.Server.Addr + webpath = `http://` + w.Server.Addr //提示 - wslog.L(`I: `,`使用WebJs`,webpath,`进行加密`) + wslog.L(`I: `, `使用WebJs`, webpath, `进行加密`) } -func Wasm(uid uintptr,rt RT) (so RT, o string) {//maxloop 超时重试 +func Wasm(uid uintptr, rt RT) (so RT, o string) { //maxloop 超时重试 so = rt - {//nodejs + { //nodejs if nodeJsUrl != "" { req := reqf.New() if err := req.Reqf(reqf.Rval{ - Header:map[string]string{ + Header: map[string]string{ `Content-Type`: `application/json`, }, - Url:nodeJsUrl, - PostStr:toNodeJsString(so), - Proxy:c.Proxy, - Timeout:3*1000, - });err != nil { - wslog.L(`E: `,err) - so,o = Wasm(uid, so) + Url: nodeJsUrl, + PostStr: toNodeJsString(so), + Proxy: c.C.Proxy, + Timeout: 3 * 1000, + }); err != nil { + wslog.L(`E: `, err) + so, o = Wasm(uid, so) return } - var res struct{ - Code int `json:"code"` - S string `json:"s"` + var res struct { + Code int `json:"code"` + S string `json:"s"` Message string `json:"message"` } - if e := json.Unmarshal(req.Respon, &res);e != nil { - wslog.L(`E: `,e) + if e := json.Unmarshal(req.Respon, &res); e != nil { + wslog.L(`E: `, e) } else if res.Code != 0 { - wslog.L(`E: `,res.Message) + wslog.L(`E: `, res.Message) } else { o = res.S } @@ -175,15 +178,15 @@ func Wasm(uid uintptr,rt RT) (so RT, o string) {//maxloop 超时重试 } } - {//web - for try:=5;try > 0 && ws.Len() == 0;try-=1 {//没有从池中取出 + { //web + for try := 5; try > 0 && ws.Len() == 0; try -= 1 { //没有从池中取出 open.Run(webpath) - wslog.L(`I: `,`浏览器打开`,webpath) - time.Sleep(time.Second*time.Duration(10)) + wslog.L(`I: `, `浏览器打开`, webpath) + time.Sleep(time.Second * time.Duration(10)) } if ws.Len() == 0 { - wslog.L(`W: `,`浏览器打开`,webpath,`失败,请手动打开`) + wslog.L(`W: `, `浏览器打开`, webpath, `失败,请手动打开`) return } @@ -192,55 +195,57 @@ func Wasm(uid uintptr,rt RT) (so RT, o string) {//maxloop 超时重试 } b, e := json.Marshal(so) if e != nil { - wslog.L(`E: `,e) + wslog.L(`E: `, e) } //获取websocket操作对象 发送 - ws.Interface().Push_tag(`send`,websocket.Uinterface{ - Id:uid, - Data:b, + ws.Interface().Push_tag(`send`, websocket.Uinterface{ + Id: uid, + Data: b, }) for { select { - case r :=<- rec_chan: - if r.Id != so.R.Id {break}//或许接收到之前的请求,校验Id字段 + case r := <-rec_chan: + if r.Id != so.R.Id { + break + } //或许接收到之前的请求,校验Id字段 return so, r.S - case <- time.After(time.Second*time.Duration(1)): - wslog.L(`E: `,`超时!响应>1s,确认保持`,webpath,`开启`) + case <-time.After(time.Second * time.Duration(1)): + wslog.L(`E: `, `超时!响应>1s,确认保持`, webpath, `开启`) return } } } } -func Close(uid uintptr){ +func Close(uid uintptr) { //nodejs不需要关闭 if nodeJsUrl != "" { return } //获取websocket操作对象 关闭 - ws.Interface().Push_tag(`close`,websocket.Uinterface{ - Id:uid, - Data:[]byte(`获取结束、关闭连接`), + ws.Interface().Push_tag(`close`, websocket.Uinterface{ + Id: uid, + Data: []byte(`获取结束、关闭连接`), }) } func test(uid uintptr) bool { - time.Sleep(time.Second*time.Duration(3)) - if _,s := Wasm(uid, RT{ - R:R{ - Id: "[9,371,1,22613059]", - Device: "[\"AUTO8216117272375373\",\"77bee604-b591-4664-845b-b69603f8c71c\"]", - Ets: 1611836581, - Benchmark: "seacasdgyijfhofiuxoannn", - Time: 60, - Ts: 1611836642190, - Ua:`Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0 Test`, + time.Sleep(time.Second * time.Duration(3)) + if _, s := Wasm(uid, RT{ + R: R{ + Id: "[9,371,1,22613059]", + Device: "[\"AUTO8216117272375373\",\"77bee604-b591-4664-845b-b69603f8c71c\"]", + Ets: 1611836581, + Benchmark: "seacasdgyijfhofiuxoannn", + Time: 60, + Ts: 1611836642190, + Ua: `Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0 Test`, }, T: []int{2, 5, 1, 4}, - });s != `e4249b7657c2d4a44955548eb814797d41ddd99bfdfa5974462b8c387d701b8c83898f6d7dde1772c67fad6a113d20c20e454be1d1627e7ea99617a8a1f99bd0` { - wslog.L(`E: `,`测试未通过`,s) + }); s != `e4249b7657c2d4a44955548eb814797d41ddd99bfdfa5974462b8c387d701b8c83898f6d7dde1772c67fad6a113d20c20e454be1d1627e7ea99617a8a1f99bd0` { + wslog.L(`E: `, `测试未通过`, s) return false } return true @@ -248,17 +253,17 @@ func test(uid uintptr) bool { func toNodeJsString(r RT) (o string) { o += `{"t":{"id":` - o += r.R.Id+`,` - o += `"device":`+r.R.Device+`,` - o += `"ets":`+strconv.Itoa(r.R.Ets)+`,` - o += `"benchmark":"`+r.R.Benchmark+`",` - o += `"time":`+strconv.Itoa(r.R.Time)+`,` - o += `"ts":`+strconv.Itoa(r.R.Ts)+`,` - o += `"ua":"`+r.R.Ua+`"},"r":[` - o += strconv.Itoa(r.T[0])+`,` - o += strconv.Itoa(r.T[1])+`,` - o += strconv.Itoa(r.T[2])+`,` + o += r.R.Id + `,` + o += `"device":` + r.R.Device + `,` + o += `"ets":` + strconv.Itoa(r.R.Ets) + `,` + o += `"benchmark":"` + r.R.Benchmark + `",` + o += `"time":` + strconv.Itoa(r.R.Time) + `,` + o += `"ts":` + strconv.Itoa(r.R.Ts) + `,` + o += `"ua":"` + r.R.Ua + `"},"r":[` + o += strconv.Itoa(r.T[0]) + `,` + o += strconv.Itoa(r.T[1]) + `,` + o += strconv.Itoa(r.T[2]) + `,` o += strconv.Itoa(r.T[3]) o += `]}` return -} \ No newline at end of file +} diff --git a/Reply/F.go b/Reply/F.go index 5fc7a29..5d98924 100644 --- a/Reply/F.go +++ b/Reply/F.go @@ -47,11 +47,11 @@ import ( /* F额外功能区 */ -var flog = c.Log.Base(`功能`) +var flog = c.C.Log.Base(`功能`) //功能开关选取函数 func IsOn(s string) bool { - v, ok := c.K_v.LoadV(s).(bool) + v, ok := c.C.K_v.LoadV(s).(bool) return ok && v } @@ -134,16 +134,16 @@ func ShowRevf() { return } if ShowRev_start { - c.Log.Base(`功能`).L(`I: `, fmt.Sprintf("营收 ¥%.2f", c.Rev)) + c.C.Log.Base(`功能`).L(`I: `, fmt.Sprintf("营收 ¥%.2f", c.C.Rev)) return } ShowRev_start = true for { - c.Log.Base(`功能`).L(`I: `, fmt.Sprintf("营收 ¥%.2f", c.Rev)) - for c.Rev == ShowRev_old { + c.C.Log.Base(`功能`).L(`I: `, fmt.Sprintf("营收 ¥%.2f", c.C.Rev)) + for c.C.Rev == ShowRev_old { p.Sys().Timeoutf(60) } - ShowRev_old = c.Rev + ShowRev_old = c.C.Rev } } @@ -187,9 +187,9 @@ func init() { `GB18030`: true, `utf-8`: true, } - if v, ok := c.K_v.LoadV("Ass编码").(string); ok { + if v, ok := c.C.K_v.LoadV("Ass编码").(string); ok { if v1, ok := accept[v]; ok && v1 { - c.Log.Base(`Ass`).L(`T: `, "编码:", v) + c.C.Log.Base(`Ass`).L(`T: `, "编码:", v) if v == `utf-8` { ass.wrap = nil } @@ -205,10 +205,10 @@ func Ass_f(file string, st time.Time) { } if rel, err := filepath.Rel(savestream.base_path, ass.file); err == nil { - c.Log.Base(`Ass`).L(`I: `, "保存到", rel+".ass") + c.C.Log.Base(`Ass`).L(`I: `, "保存到", rel+".ass") } else { - c.Log.Base(`Ass`).L(`I: `, "保存到", ass.file+".ass") - c.Log.Base(`Ass`).L(`W: `, err) + c.C.Log.Base(`Ass`).L(`I: `, "保存到", ass.file+".ass") + c.C.Log.Base(`Ass`).L(`W: `, err) } p.File().FileWR(p.Filel{ File: ass.file + ".ass", @@ -309,7 +309,7 @@ var savestream = Savestream{ func init() { //使用带tag的消息队列在功能间传递消息 - c.Danmu_Main_mq.Pull_tag(msgq.FuncMap{ + c.C.Danmu_Main_mq.Pull_tag(msgq.FuncMap{ `savestream`: func(data interface{}) bool { if savestream.cancel.Islive() { Savestream_wait() @@ -321,22 +321,22 @@ func init() { }, }) //base_path - if path, ok := c.K_v.LoadV("直播流保存位置").(string); ok { + if path, ok := c.C.K_v.LoadV("直播流保存位置").(string); ok { if path, err := filepath.Abs(path); err == nil { savestream.base_path = path + "/" } } - if v, ok := c.K_v.LoadV(`直播hls流缓冲`).(float64); ok && v > 0 { + if v, ok := c.C.K_v.LoadV(`直播hls流缓冲`).(float64); ok && v > 0 { savestream.hlsbuffersize = int(v) } - if v, ok := c.K_v.LoadV(`直播hls流均衡`).(bool); ok { + if v, ok := c.C.K_v.LoadV(`直播hls流均衡`).(bool); ok { savestream.hls_banlance_host = v } } //已go func形式调用,将会获取直播流 func Savestreamf() { - l := c.Log.Base(`savestream`) + l := c.C.Log.Base(`savestream`) //避免多次开播导致的多次触发 { @@ -347,13 +347,13 @@ func Savestreamf() { defer savestream.skipFunc.UnSet() } - want_qn, ok := c.K_v.LoadV("直播流清晰度").(float64) + want_qn, ok := c.C.K_v.LoadV("直播流清晰度").(float64) if !ok || want_qn < 0 { return } - c.Live_want_qn = int(want_qn) + c.C.Live_want_qn = int(want_qn) - F.Get(`Live`) + F.Get(&c.C).Get(`Live`) if savestream.cancel.Islive() { return @@ -362,7 +362,7 @@ func Savestreamf() { //random host load balance Host_list := []string{} if savestream.hls_banlance_host { - for _, v := range c.Live { + for _, v := range c.C.Live { url_struct, e := url.Parse(v) if e != nil { continue @@ -394,7 +394,7 @@ func Savestreamf() { ConnectTimeout: 2000, ReadTimeout: 1000, Timeout: 2000, - Proxy: c.Proxy, + Proxy: c.C.Proxy, Header: map[string]string{ `Host`: m3u8_url.Host, `User-Agent`: `Mozilla/5.0 (X11; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0`, @@ -544,25 +544,25 @@ func Savestreamf() { ) for { - F.Get(`Liveing`) - if !c.Liveing { + F.Get(&c.C).Get(`Liveing`) + if !c.C.Liveing { break } - F.Get(`Live`) - if len(c.Live) == 0 { + F.Get(&c.C).Get(`Live`) + if len(c.C.Live) == 0 { break } savestream.path = savestream.base_path - savestream.path += strconv.Itoa(c.Roomid) + "_" + time.Now().Format("2006_01_02_15-04-05-000") + savestream.path += strconv.Itoa(c.C.Roomid) + "_" + time.Now().Format("2006_01_02_15-04-05-000") savestream.wait = s.Init() savestream.cancel = s.Init() CookieM := make(map[string]string) - c.Cookie.Range(func(k, v interface{}) bool { + c.C.Cookie.Range(func(k, v interface{}) bool { CookieM[k.(string)] = v.(string) return true }) @@ -575,10 +575,10 @@ func Savestreamf() { }() l.L(`I: `, "尝试连接live") if e := r.Reqf(reqf.Rval{ - Url: c.Live[0], + Url: c.C.Live[0], Retry: 10, SleepTime: 1000, - Proxy: c.Proxy, + Proxy: c.C.Proxy, Header: map[string]string{ `Cookie`: reqf.Map_2_Cookies_String(CookieM), }, @@ -603,7 +603,7 @@ func Savestreamf() { } } - if strings.Contains(c.Live[0], "flv") { + if strings.Contains(c.C.Live[0], "flv") { if rel, err := filepath.Rel(savestream.base_path, savestream.path); err == nil { l.L(`I: `, "保存到", rel+".flv") } else { @@ -817,10 +817,10 @@ func Savestreamf() { //随机选取服务器,获取超时时间 live_index := 0 - if len(c.Live) > 0 { - live_index = int(p.Rand().MixRandom(0, int64(len(c.Live)-1))) + if len(c.C.Live) > 0 { + live_index = int(p.Rand().MixRandom(0, int64(len(c.C.Live)-1))) } - link, exp, e := flv_get_link(c.Live[live_index]) + link, exp, e := flv_get_link(c.C.Live[live_index]) if e != nil { l.L(`W: `, `流链接获取错误`, e) break @@ -855,7 +855,7 @@ func Savestreamf() { } }(req, reqf.Rval{ Url: link, - Proxy: c.Proxy, + Proxy: c.C.Proxy, Header: map[string]string{ `Cookie`: reqf.Map_2_Cookies_String(CookieM), }, @@ -932,7 +932,7 @@ func Savestreamf() { expires := int64(exp) - p.Sys().GetSTime() - 120 // no expect qn - if c.Live_want_qn < c.Live_qn { + if c.C.Live_want_qn < c.C.Live_qn { expires = time.Now().Add(time.Minute * 2).Unix() } @@ -954,13 +954,13 @@ func Savestreamf() { l.L(`I: `, "flv关闭,开始新连接") - //即将过期,刷新c.Live - F.Get(`Liveing`) - if !c.Liveing { + //即将过期,刷新c.C.Live + F.Get(&c.C).Get(`Liveing`) + if !c.C.Liveing { break } - F.Get(`Live`) - if len(c.Live) == 0 { + F.Get(&c.C).Get(`Live`) + if len(c.C.Live) == 0 { break } } @@ -1221,7 +1221,7 @@ func Savestreamf() { ConnectTimeout: 5000, ReadTimeout: 1000, Retry: 1, - Proxy: c.Proxy, + Proxy: c.C.Proxy, }); e != nil && !errors.Is(e, io.EOF) { l.L(`I: `, e) v.status = s_fail @@ -1236,7 +1236,7 @@ func Savestreamf() { break } - links, file_add, exp, e := hls_get_link(c.Live, last_download) + links, file_add, exp, e := hls_get_link(c.C.Live, last_download) if e != nil { if e == no_Modified { time.Sleep(time.Duration(2) * time.Second) @@ -1276,7 +1276,7 @@ func Savestreamf() { } //qn in expect , set expires - if c.Live_want_qn >= c.Live_qn { + if c.C.Live_want_qn >= c.C.Live_qn { expires = int64(exp) } @@ -1327,10 +1327,10 @@ func Savestreamf() { } else if len(links) > 100 { l.L(`W: `, `重试,等待下载切片:`, len(links)) - if F.Get(`Liveing`); !c.Liveing { + if F.Get(&c.C).Get(`Liveing`); !c.C.Liveing { break } - if F.Get(`Live`); len(c.Live) == 0 { + if F.Get(&c.C).Get(`Live`); len(c.C.Live) == 0 { break } @@ -1377,7 +1377,7 @@ func Savestreamf() { ConnectTimeout: 2000, ReadTimeout: 1000, Timeout: 2000, - Proxy: c.Proxy, + Proxy: c.C.Proxy, }); e != nil { //try other host if index+1 < len(Host_list) { @@ -1419,10 +1419,10 @@ func Savestreamf() { //m3u8_url 将过期 if p.Sys().GetSTime()+60 > expires { - if F.Get(`Liveing`); !c.Liveing { + if F.Get(&c.C).Get(`Liveing`); !c.C.Liveing { break } - if F.Get(`Live`); len(c.Live) == 0 { + if F.Get(&c.C).Get(`Live`); len(c.C.Live) == 0 { break } // set expect @@ -1480,7 +1480,7 @@ func Savestream_wait() { } savestream.cancel.Done() - c.Log.Base(`savestream`).L(`I: `, "等待停止") + c.C.Log.Base(`savestream`).L(`I: `, "等待停止") savestream.wait.Wait() } @@ -1498,7 +1498,7 @@ func Obsf(on bool) { if !IsOn("调用obs") { return } - l := c.Log.Base(`obs`) + l := c.C.Log.Base(`obs`) if on { if p.Sys().CheckProgram("obs")[0] != 0 { @@ -1534,7 +1534,7 @@ func Obs_R(on bool) { return } - l := c.Log.Base("obs_R") + l := c.C.Log.Base("obs_R") if p.Sys().CheckProgram("obs")[0] == 0 { l.L(`W: `, "obs未启动") @@ -1634,7 +1634,7 @@ func Autobanf(s string) bool { } //ban字符重复低去除 res = append(res, pt) } - l := c.Log.Base("autoban") + l := c.C.Log.Base("autoban") l.L(`W: `, res) return true } @@ -1698,10 +1698,10 @@ func Danmuji_auto() { list []string timeout int ) - for _, v := range c.K_v.LoadV(`自动弹幕机_内容`).([]interface{}) { + for _, v := range c.C.K_v.LoadV(`自动弹幕机_内容`).([]interface{}) { list = append(list, v.(string)) } - timeout = int(c.K_v.LoadV(`自动弹幕机_发送间隔s`).(float64)) + timeout = int(c.C.K_v.LoadV(`自动弹幕机_发送间隔s`).(float64)) if timeout < 5 { timeout = 5 } @@ -1746,9 +1746,9 @@ func init() { } autoskip.now += 1 autoskip.Lock() - if autoskip.roomid != c.Roomid { + if autoskip.roomid != c.C.Roomid { autoskip.buf = make(map[string]Autoskip_item) - autoskip.roomid = c.Roomid + autoskip.roomid = c.C.Roomid flog.Base_add(`弹幕合并`).L(`T: `, `房间更新:`, autoskip.roomid) autoskip.Unlock() continue @@ -1758,7 +1758,7 @@ func init() { delete(autoskip.buf, k) { //超时显示 if v.Num > 3 { - c.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ //传入消息队列 + c.C.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ //传入消息队列 uid: `0multi`, m: map[string]string{ `{num}`: strconv.Itoa(int(v.Num)), @@ -1798,9 +1798,9 @@ func Autoskipf(s string) uint { } autoskip.Lock() defer autoskip.Unlock() - if autoskip.roomid != c.Roomid { + if autoskip.roomid != c.C.Roomid { autoskip.buf = make(map[string]Autoskip_item) - autoskip.roomid = c.Roomid + autoskip.roomid = c.C.Roomid flog.Base_add(`弹幕合并`).L(`T: `, `房间更新:`, autoskip.roomid) return 0 } @@ -1835,7 +1835,7 @@ var lessdanmu = Lessdanmu{ } func init() { - if max_num, ok := c.K_v.LoadV(`每秒显示弹幕数`).(float64); ok && int(max_num) >= 1 { + if max_num, ok := c.C.K_v.LoadV(`每秒显示弹幕数`).(float64); ok && int(max_num) >= 1 { flog.Base_add(`更少弹幕`).L(`T: `, `每秒弹幕数:`, int(max_num)) lessdanmu.max_num = int(max_num) lessdanmu.limit = limit.New(int(max_num), 1000, 0) //timeout right now @@ -1846,9 +1846,9 @@ func Lessdanmuf(s string) (show bool) { if !IsOn("相似弹幕忽略") { return true } - if lessdanmu.roomid != c.Roomid { + if lessdanmu.roomid != c.C.Roomid { lessdanmu.buf = nil - lessdanmu.roomid = c.Roomid + lessdanmu.roomid = c.C.Roomid lessdanmu.threshold = 0.7 flog.Base_add(`更少弹幕`).L(`T: `, `房间更新:`, lessdanmu.roomid) return true @@ -2003,7 +2003,7 @@ func Jiezouf(s []string) bool { jiezou.Lock() if now > 1.3*jiezou.avg { //触发 - c.Log.Base("jiezou").L(`W: `, "节奏注意", now, jiezou.avg, S) + c.C.Log.Base("jiezou").L(`W: `, "节奏注意", now, jiezou.avg, S) jiezou.avg = now //沉默 jiezou.Unlock() @@ -2020,7 +2020,7 @@ func Jiezouf(s []string) bool { //保存所有消息到json func init() { Save_to_json(0, []interface{}{`[`}) - c.Danmu_Main_mq.Pull_tag(msgq.FuncMap{ + c.C.Danmu_Main_mq.Pull_tag(msgq.FuncMap{ `change_room`: func(data interface{}) bool { //房间改变 Save_to_json(0, []interface{}{`[`}) return false @@ -2033,7 +2033,7 @@ func init() { } func Save_to_json(Loc int, Context []interface{}) { - if path, ok := c.K_v.LoadV(`save_to_json`).(string); ok && path != `` { + if path, ok := c.C.K_v.LoadV(`save_to_json`).(string); ok && path != `` { p.File().FileWR(p.Filel{ File: path, Loc: int64(Loc), @@ -2047,33 +2047,33 @@ func Entry_danmu() { flog := flog.Base_add(`进房弹幕`) //检查与切换粉丝牌,只在cookie存在时启用 - F.Get(`CheckSwitch_FansMedal`) + F.Get(&c.C).Get(`CheckSwitch_FansMedal`) - if v, _ := c.K_v.LoadV(`进房弹幕_有粉丝牌时才发`).(bool); v && c.Wearing_FansMedal == 0 { + if v, _ := c.C.K_v.LoadV(`进房弹幕_有粉丝牌时才发`).(bool); v && c.C.Wearing_FansMedal == 0 { flog.L(`T: `, `无粉丝牌`) return } - if v, _ := c.K_v.LoadV(`进房弹幕_仅发首日弹幕`).(bool); v { + if v, _ := c.C.K_v.LoadV(`进房弹幕_仅发首日弹幕`).(bool); v { res := F.Get_weared_medal() if res.TodayIntimacy > 0 { flog.L(`T: `, `今日已发弹幕`) return } } - if array, ok := c.K_v.LoadV(`进房弹幕_内容`).([]interface{}); ok && len(array) != 0 { + if array, ok := c.C.K_v.LoadV(`进房弹幕_内容`).([]interface{}); ok && len(array) != 0 { rand := p.Rand().MixRandom(0, int64(len(array)-1)) - send.Danmu_s(array[rand].(string), c.Roomid) + send.Danmu_s(array[rand].(string), c.C.Roomid) } } //保持所有牌子点亮 func Keep_medal_light() { - if v, _ := c.K_v.LoadV(`保持牌子亮着`).(bool); !v { + if v, _ := c.C.K_v.LoadV(`保持牌子亮着`).(bool); !v { return } flog := flog.Base_add(`保持亮牌`) - array, ok := c.K_v.LoadV(`进房弹幕_内容`).([]interface{}) + array, ok := c.C.K_v.LoadV(`进房弹幕_内容`).([]interface{}) if !ok || len(array) == 0 { flog.L(`I: `, `进房弹幕_内容 为 空,退出`) return @@ -2128,15 +2128,15 @@ func Keep_medal_light() { //自动发送即将过期的银瓜子礼物 func AutoSend_silver_gift() { - day, _ := c.K_v.LoadV(`发送还有几天过期的礼物`).(float64) + day, _ := c.C.K_v.LoadV(`发送还有几天过期的礼物`).(float64) if day <= 0 { return } flog := flog.Base_add(`自动送礼`).L(`T: `, `开始`) - if c.UpUid == 0 { - F.Get(`UpUid`) + if c.C.UpUid == 0 { + F.Get(&c.C).Get(`UpUid`) } var hasSend bool @@ -2187,7 +2187,7 @@ func get_m4s_cache(path string) (buf []byte, cached bool, err error) { //直播Web服务口 func init() { flog := flog.Base_add(`直播Web服务`) - if port_f, ok := c.K_v.LoadV(`直播Web服务口`).(float64); ok && port_f >= 0 { + if port_f, ok := c.C.K_v.LoadV(`直播Web服务口`).(float64); ok && port_f >= 0 { port := int(port_f) base_dir := savestream.base_path @@ -2424,7 +2424,7 @@ func init() { } path := filepath.Base(savestream.path) - if strings.Contains(c.Live[0], "flv") { + if strings.Contains(c.C.Live[0], "flv") { path += ".flv.dtmp" } else { path += "/0.m3u8.dtmp" @@ -2460,8 +2460,8 @@ func init() { }, }) host := p.Sys().GetIntranetIp() - c.Stream_url = strings.Replace(`http://`+s.Server.Addr, `0.0.0.0`, host, -1) - flog.L(`I: `, `启动于`, c.Stream_url) + c.C.Stream_url = strings.Replace(`http://`+s.Server.Addr, `0.0.0.0`, host, -1) + flog.L(`I: `, `启动于`, c.C.Stream_url) } } @@ -2474,7 +2474,7 @@ type Communicate struct { func init() { communicate.Buf = new(psync.Map) - c.Danmu_Main_mq.Pull_tag(msgq.FuncMap{ + c.C.Danmu_Main_mq.Pull_tag(msgq.FuncMap{ `change_room`: func(data interface{}) bool { //房间改变 communicate.Reset() return false diff --git a/Reply/Msg.go b/Reply/Msg.go index f82d0fe..fe74af5 100644 --- a/Reply/Msg.go +++ b/Reply/Msg.go @@ -11,7 +11,7 @@ import ( 数据为WS_OP_MESSAGE类型的数据分派 */ -var msglog = c.Log.Base(`Msg`) +var msglog = c.C.Log.Base(`Msg`) //Msg类型数据处理方法map var Msg_map = map[string]func(replyF, string){ diff --git a/Reply/Reply.go b/Reply/Reply.go index b3e47b4..58fb8c8 100644 --- a/Reply/Reply.go +++ b/Reply/Reply.go @@ -17,7 +17,7 @@ import ( mq "github.com/qydysky/part/msgq" ) -var reply_log = c.Log.Base(`Reply`) +var reply_log = c.C.Log.Base(`Reply`) //返回数据分派 //传入接受到的ws数据 @@ -147,7 +147,7 @@ func (replyF) vtr_gift_lottery(s string) { return } { //语言tts - c.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ + c.C.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ uid: `0room`, m: map[string]string{ `{msg}`: j.Data.InteractMsg, @@ -167,7 +167,7 @@ func (replyF) interact_word(s string) { uname := p.Json().GetValFromS(s, "data.uname") if v, ok := uname.(string); ok { { //语言tts - c.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ + c.C.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ uid: `0follow`, msg: fmt.Sprint(v + `关注了直播间`), }) @@ -278,10 +278,10 @@ func (replyF) user_toast_msg(s string) { } if price != 0 { sh_log = append(sh, "¥", price/1000) //不在界面显示价格 - c.Danmu_Main_mq.Push_tag(`c.Rev_add`, float64(price)/1000) + c.C.Danmu_Main_mq.Push_tag(`c.Rev_add`, float64(price)/1000) } { //语言tts - c.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ //传入消息队列 + c.C.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ //传入消息队列 uid: `0buyguide`, m: map[string]string{ `{username}`: username, @@ -294,17 +294,17 @@ func (replyF) user_toast_msg(s string) { } { //额外 ass 私信 Assf(fmt.Sprintln(sh...)) - c.Danmu_Main_mq.Push_tag(`guard_update`, nil) //使用连续付费的新舰长无法区分,刷新舰长数 + c.C.Danmu_Main_mq.Push_tag(`guard_update`, nil) //使用连续付费的新舰长无法区分,刷新舰长数 if uid != 0 { - c.Danmu_Main_mq.Push_tag(`pm`, send.Pm_item{ + c.C.Danmu_Main_mq.Push_tag(`pm`, send.Pm_item{ Uid: uid, - Msg: c.K_v.LoadV(`上舰私信`).(string), + Msg: c.C.K_v.LoadV(`上舰私信`).(string), }) //上舰私信 } - if c.K_v.LoadV(`额外私信对象`).(float64) != 0 { - c.Danmu_Main_mq.Push_tag(`pm`, send.Pm_item{ - Uid: int(c.K_v.LoadV(`额外私信对象`).(float64)), - Msg: c.K_v.LoadV(`上舰私信(额外)`).(string), + if c.C.K_v.LoadV(`额外私信对象`).(float64) != 0 { + c.C.Danmu_Main_mq.Push_tag(`pm`, send.Pm_item{ + Uid: int(c.C.K_v.LoadV(`额外私信对象`).(float64)), + Msg: c.C.K_v.LoadV(`上舰私信(额外)`).(string), }) //上舰私信-对额外 } } @@ -326,7 +326,7 @@ var ( ) func (replyF) heartbeat(s int) { - c.Danmu_Main_mq.Push_tag(`c.Renqi`, s) //使用连续付费的新舰长无法区分,刷新舰长数 + c.C.Danmu_Main_mq.Push_tag(`c.Renqi`, s) //使用连续付费的新舰长无法区分,刷新舰长数 if s == 1 { return } //人气为1,不输出 @@ -453,7 +453,7 @@ func (replyF) room_change(s string) { if title != nil { sh = append(sh, title) - c.Title = title.(string) + c.C.Title = title.(string) } if area_name != nil { sh = append(sh, area_name) @@ -527,7 +527,7 @@ func (replyF) send_gift(s string) { if total_coin != 0 { allprice = float64(total_coin) / 1000 sh_log = append(sh, fmt.Sprintf("¥%.1f", allprice)) //不在界面显示价格 - c.Danmu_Main_mq.Push_tag(`c.Rev_add`, allprice) + c.C.Danmu_Main_mq.Push_tag(`c.Rev_add`, allprice) } if len(sh) == 0 { @@ -537,7 +537,7 @@ func (replyF) send_gift(s string) { //小于设定 { var tmp = 20.0 - if v, ok := c.K_v.Load(`弹幕_礼物金额显示阈值`); ok { + if v, ok := c.C.K_v.Load(`弹幕_礼物金额显示阈值`); ok { tmp = v.(float64) } if allprice < tmp { @@ -548,7 +548,7 @@ func (replyF) send_gift(s string) { } { //语言tts - c.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ //传入消息队列 + c.C.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ //传入消息队列 uid: `0gift`, m: map[string]string{ `{num}`: strconv.Itoa(num), @@ -595,7 +595,7 @@ func (replyF) preparing(s string) { Obsf(false) Savestream_wait() go ShowRevf() - c.Liveing = false + c.C.Liveing = false } if p.Sys().Type(roomid) == "float64" { Gui_show(Itos([]interface{}{"房间", roomid, "下播了"}), "0room") @@ -621,9 +621,9 @@ func (replyF) live(s string) { go Savestreamf() } { - c.Rev = 0.0 //营收 - c.Liveing = true //直播i标志 - c.Live_Start_Time = time.Now() //开播h时间 + c.C.Rev = 0.0 //营收 + c.C.Liveing = true //直播i标志 + c.C.Live_Start_Time = time.Now() //开播h时间 } if p.Sys().Type(roomid) == "float64" { Gui_show(Itos([]interface{}{"房间", roomid, "开播了"}), "0room") @@ -678,7 +678,7 @@ func (replyF) super_chat_message(s string) { if price != 0 { sh = append(sh, "\n") //界面不显示价格 logg = append(logg, "¥", price) - c.Danmu_Main_mq.Push_tag(`c.Rev_add`, float64(price)) + c.C.Danmu_Main_mq.Push_tag(`c.Rev_add`, float64(price)) } fmt.Println("====") fmt.Println(sh...) @@ -690,7 +690,7 @@ func (replyF) super_chat_message(s string) { logg = append(logg, message) } { //语言tts - c.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ //传入消息队列 + c.C.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ //传入消息队列 uid: `0superchat`, m: map[string]string{ `{uname}`: uname, @@ -725,7 +725,7 @@ func (replyF) panel(s string) { return } else { if v, ok := note.(string); ok { - c.Note = v + c.C.Note = v } fmt.Println("排行", note) msglog.L(`I: `, "排行", note) @@ -741,14 +741,14 @@ func (replyF) hot_rank_changed(s string) { msglog.L(`E: `, e) } if type_item.Data.Area_name != `` { - c.Note = type_item.Data.Area_name + " " + c.C.Note = type_item.Data.Area_name + " " if type_item.Data.Rank == 0 { - c.Note += "50+" + c.C.Note += "50+" } else { - c.Note += strconv.Itoa(type_item.Data.Rank) + c.C.Note += strconv.Itoa(type_item.Data.Rank) } - fmt.Printf("%s\t%s\n", "热门榜", c.Note) - msglog.L(`I: `, "热门榜", c.Note) + fmt.Printf("%s\t%s\n", "热门榜", c.C.Note) + msglog.L(`I: `, "热门榜", c.C.Note) } } @@ -761,14 +761,14 @@ func (replyF) hot_rank_changed_v2(s string) { msglog.L(`E: `, e) } if type_item.Data.AreaName != `` { - c.Note = type_item.Data.AreaName + " " + c.C.Note = type_item.Data.AreaName + " " if type_item.Data.Rank == 0 { - c.Note += "50+" + c.C.Note += "50+" } else { - c.Note += strconv.Itoa(type_item.Data.Rank) + c.C.Note += strconv.Itoa(type_item.Data.Rank) } - fmt.Printf("%s\t%s\n", "热门榜", c.Note) - msglog.L(`I: `, "热门榜", c.Note) + fmt.Printf("%s\t%s\n", "热门榜", c.C.Note) + msglog.L(`I: `, "热门榜", c.C.Note) } } @@ -788,7 +788,7 @@ func (replyF) hot_rank_settlement(s string) { tmp += strconv.Itoa(type_item.Data.Rank) } Gui_show(tmp, "0rank") - c.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ //传入消息队列 + c.C.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ //传入消息队列 uid: "0rank", m: map[string]string{ `{Area_name}`: type_item.Data.Area_name, @@ -814,7 +814,7 @@ func (replyF) hot_rank_settlement_v2(s string) { tmp += strconv.Itoa(type_item.Data.Rank) } Gui_show(tmp, "0rank") - c.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ //传入消息队列 + c.C.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ //传入消息队列 uid: "0rank", m: map[string]string{ `{Area_name}`: type_item.Data.AreaName, @@ -889,7 +889,7 @@ func (replyF) entry_effect(s string) { } { //语言tts - c.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ //传入消息队列 + c.C.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ //传入消息队列 uid: img, m: map[string]string{ `{guard_name}`: guard_name, @@ -973,7 +973,7 @@ func (replyF) danmu(s string) { item.auth = i[1] } } - item.roomid = c.Roomid + item.roomid = c.C.Roomid } msglog := msglog.Log_show_control(false) @@ -1013,11 +1013,11 @@ func Msg_senddanmu(msg string) { `bili_jct`, `DedeUserID`, `LIVE_BUVID`, - }); len(missKey) != 0 || c.Roomid == 0 { + }); len(missKey) != 0 || c.C.Roomid == 0 { msglog.L(`E: `, `c.Roomid == 0 || Cookie无Key:`, missKey) return } - send.Danmu_s(msg, c.Roomid) + send.Danmu_s(msg, c.C.Roomid) } //弹幕显示 @@ -1027,7 +1027,7 @@ func Msg_showdanmu(item Danmu_item) { msglog := msglog.Log_show_control(false) //room change - if item.roomid != 0 && item.roomid != c.Roomid { + if item.roomid != 0 && item.roomid != c.C.Roomid { return } @@ -1043,7 +1043,7 @@ func Msg_showdanmu(item Danmu_item) { { //语言tts 私信 if item.uid != "" { if item.auth != nil { - c.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ //传入消息队列 + c.C.Danmu_Main_mq.Push_tag(`tts`, Danmu_mq_t{ //传入消息队列 uid: item.uid, m: map[string]string{ `{auth}`: fmt.Sprint(item.auth), @@ -1052,15 +1052,15 @@ func Msg_showdanmu(item Danmu_item) { }) } if i, e := strconv.Atoi(item.uid); e == nil { - c.Danmu_Main_mq.Push_tag(`pm`, send.Pm_item{ + c.C.Danmu_Main_mq.Push_tag(`pm`, send.Pm_item{ Uid: i, - Msg: c.K_v.LoadV(`弹幕私信`).(string), + Msg: c.C.K_v.LoadV(`弹幕私信`).(string), }) //上舰私信 } - if c.K_v.LoadV(`额外私信对象`).(float64) != 0 { - c.Danmu_Main_mq.Push_tag(`pm`, send.Pm_item{ - Uid: int(c.K_v.LoadV(`额外私信对象`).(float64)), - Msg: c.K_v.LoadV(`弹幕私信(额外)`).(string), + if c.C.K_v.LoadV(`额外私信对象`).(float64) != 0 { + c.C.Danmu_Main_mq.Push_tag(`pm`, send.Pm_item{ + Uid: int(c.C.K_v.LoadV(`额外私信对象`).(float64)), + Msg: c.C.K_v.LoadV(`弹幕私信(额外)`).(string), }) //上舰私信-对额外 } } diff --git a/Reply/flvDecode.go b/Reply/flvDecode.go index b4c9324..67ef978 100644 --- a/Reply/flvDecode.go +++ b/Reply/flvDecode.go @@ -1,11 +1,12 @@ package reply import ( - "os" - "fmt" "bytes" - "time" "errors" + "fmt" + "os" + "time" + // "math" c "github.com/qydysky/bili_danmu/CV" @@ -15,12 +16,12 @@ import ( ) const ( - flv_header_size = 9 - tag_header_size = 11 + flv_header_size = 9 + tag_header_size = 11 previou_tag_size = 4 - video_tag = byte(0x09) - audio_tag = byte(0x08) + video_tag = byte(0x09) + audio_tag = byte(0x08) script_tag = byte(0x12) //custom define @@ -28,14 +29,14 @@ const ( ) var ( - flv_header_sign = []byte{0x46,0x4c,0x56} - flvlog = c.Log.Base(`flv解码`) - send_sign = []byte{0x00} + flv_header_sign = []byte{0x46, 0x4c, 0x56} + flvlog = c.C.Log.Base(`flv解码`) + send_sign = []byte{0x00} ) type flv_source struct { - buf []byte - Rval reqf.Rval + buf []byte + Rval reqf.Rval Inuse bool } @@ -78,18 +79,18 @@ type flv_source struct { // } type flv_tag struct { - Tag byte - Offset int64 + Tag byte + Offset int64 Timestamp int32 - PreSize int32 + PreSize int32 FirstByte byte - Buf *[]byte + Buf *[]byte } // func Tag_stream(c chan []byte,co chan []byte) ( bool) { // //check channel // if c == nil || co == nil {return} - + // var ( // buf []byte // seach_stream_tag = func(buf []byte)(front_buf []byte,available_offset int64){ @@ -154,11 +155,11 @@ type flv_tag struct { // return true // } -func Stream(path string,front_buf *[]byte,streamChan chan []byte,cancel chan struct{}) (error) { - flvlog.L(`T: `,path) - defer flvlog.L(`T: `,`退出`) +func Stream(path string, front_buf *[]byte, streamChan chan []byte, cancel chan struct{}) error { + flvlog.L(`T: `, path) + defer flvlog.L(`T: `, `退出`) //file - f,err := os.OpenFile(path,os.O_RDONLY,0644) + f, err := os.OpenFile(path, os.O_RDONLY, 0644) if err != nil { return err } @@ -168,32 +169,36 @@ func Stream(path string,front_buf *[]byte,streamChan chan []byte,cancel chan str //get flv header(9byte) + FirstTagSize(4byte) { buf := make([]byte, flv_header_size+previou_tag_size) - if _,err := f.Read(buf);err != nil {return err} - if bytes.Index(buf,flv_header_sign) != 0 {return errors.New(`no flv`)} + if _, err := f.Read(buf); err != nil { + return err + } + if bytes.Index(buf, flv_header_sign) != 0 { + return errors.New(`no flv`) + } *front_buf = append(*front_buf, buf...) } type flv_tag struct { - Tag byte - Offset int64 + Tag byte + Offset int64 Timestamp int32 - PreSize int32 + PreSize int32 FirstByte byte - Buf *[]byte + Buf *[]byte } - var seachtag = func(f *os.File, begin_offset int64)(available_offset int64){ + var seachtag = func(f *os.File, begin_offset int64) (available_offset int64) { available_offset += begin_offset - f.Seek(begin_offset, 0)//seek to begin + f.Seek(begin_offset, 0) //seek to begin buf := make([]byte, 1024*1024*10) - if size,_ := f.Read(buf);size == 0 { + if size, _ := f.Read(buf); size == 0 { return } else { - for buf_offset:=0;buf_offset 2 { // last_timestamps = append(last_timestamps[1:], t.Timestamp) last_keyframe_video_offsets = append(last_keyframe_video_offsets[1:], t.Offset) @@ -275,15 +280,17 @@ func Stream(path string,front_buf *[]byte,streamChan chan []byte,cancel chan str first_audio_tag = true *front_buf = append(*front_buf, *t.Buf...) } - } else {//eof_tag - break; + } else { //eof_tag + break } } //seed to the second last tag - if len(last_keyframe_video_offsets) == 0 {flvlog.L(`W: `,`no keyframe`);return errors.New(`no keyframe`)} - f.Seek(last_keyframe_video_offsets[0],0) - + if len(last_keyframe_video_offsets) == 0 { + flvlog.L(`W: `, `no keyframe`) + return errors.New(`no keyframe`) + } + f.Seek(last_keyframe_video_offsets[0], 0) // var ( // last_video_keyframe_timestramp int32 @@ -297,19 +304,20 @@ func Stream(path string,front_buf *[]byte,streamChan chan []byte,cancel chan str for { //退出 select { - case <-cancel:return nil; - default:; + case <-cancel: + return nil + default: } t := getTag(f) if t.Tag == eof_tag { - f.Seek(last_available_offset,0) + f.Seek(last_available_offset, 0) time.Sleep(time.Second) continue } else if t.PreSize == 0 { - f.Seek(seachtag(f, last_available_offset),0) + f.Seek(seachtag(f, last_available_offset), 0) continue } else if t.Tag == video_tag { - if t.FirstByte & 0xf0 == 0x10 { + if t.FirstByte&0xf0 == 0x10 { streamChan <- buf buf = []byte{} } @@ -317,9 +325,9 @@ func Stream(path string,front_buf *[]byte,streamChan chan []byte,cancel chan str } else if t.Tag == audio_tag { buf = append(buf, *t.Buf...) } else if t.Tag != script_tag { - ; + } - + last_available_offset = t.Offset } @@ -328,9 +336,9 @@ func Stream(path string,front_buf *[]byte,streamChan chan []byte,cancel chan str return nil } -func TimeStramp_Check(path string) (error) { +func TimeStramp_Check(path string) error { //file - f,err := os.OpenFile(path,os.O_RDONLY,0644) + f, err := os.OpenFile(path, os.O_RDONLY, 0644) if err != nil { return err } @@ -339,46 +347,50 @@ func TimeStramp_Check(path string) (error) { //get flv header(9byte) + FirstTagSize(4byte) { buf := make([]byte, flv_header_size+previou_tag_size) - if _,err := f.Read(buf);err != nil {return err} - if bytes.Index(buf,flv_header_sign) != 0 {return errors.New(`no flv`)} + if _, err := f.Read(buf); err != nil { + return err + } + if bytes.Index(buf, flv_header_sign) != 0 { + return errors.New(`no flv`) + } } type flv_tag struct { - Tag byte - Offset int64 + Tag byte + Offset int64 Timestamp int32 - PreSize int32 + PreSize int32 FirstByte byte } //get tag func - var getTag = func(f *os.File)(t flv_tag){ - t.Offset,_ = f.Seek(0,1) + var getTag = func(f *os.File) (t flv_tag) { + t.Offset, _ = f.Seek(0, 1) buf := make([]byte, tag_header_size) - if size,err := f.Read(buf);err != nil || size == 0 { + if size, err := f.Read(buf); err != nil || size == 0 { t.Tag = eof_tag return } t.Tag = buf[0] - t.Timestamp = F.Btoi32([]byte{buf[7],buf[4],buf[5],buf[6]},0) + t.Timestamp = F.Btoi32([]byte{buf[7], buf[4], buf[5], buf[6]}, 0) - size := F.Btoi32(append([]byte{0x00},buf[1:4]...),0) + size := F.Btoi32(append([]byte{0x00}, buf[1:4]...), 0) data := make([]byte, size) - if size,err := f.Read(data);err != nil || size == 0 { + if size, err := f.Read(data); err != nil || size == 0 { t.Tag = eof_tag return } t.FirstByte = data[0] pre_tag := make([]byte, previou_tag_size) - if size,err := f.Read(pre_tag);err != nil || size == 0 { + if size, err := f.Read(pre_tag); err != nil || size == 0 { t.Tag = eof_tag return - } - t.PreSize = F.Btoi32(pre_tag,0) - + } + t.PreSize = F.Btoi32(pre_tag, 0) + // if t.PreSize == 0{fmt.Println(t.Tag,size,data[size:])} return @@ -396,15 +408,17 @@ func TimeStramp_Check(path string) (error) { continue } else if t.Tag == video_tag || t.Tag == audio_tag { if t.Timestamp < lasttimestramp { - fmt.Printf("error: now %d < pre %d\n",t.Timestamp,lasttimestramp) + fmt.Printf("error: now %d < pre %d\n", t.Timestamp, lasttimestramp) lasttimestramp = t.Timestamp continue } - fmt.Printf("%d\n",t.Timestamp) + fmt.Printf("%d\n", t.Timestamp) lasttimestramp = t.Timestamp - if lasttimestramp > 10000 {return nil} - } else {//eof_tag - break; + if lasttimestramp > 10000 { + return nil + } + } else { //eof_tag + break } } fmt.Printf("ok\n") @@ -413,19 +427,19 @@ func TimeStramp_Check(path string) (error) { // this fuction read []byte and return flv header and all complete keyframe if possible. // complete keyframe means the video and audio tags between two video key frames tag -func Seach_stream_tag(buf []byte)(front_buf []byte, keyframe[][]byte,err error){ +func Seach_stream_tag(buf []byte) (front_buf []byte, keyframe [][]byte, err error) { //get flv header(9byte) + FirstTagSize(4byte) - if header_offset := bytes.Index(buf,flv_header_sign);header_offset != -1 { - front_buf = buf[header_offset:header_offset+flv_header_size+previou_tag_size] + if header_offset := bytes.Index(buf, flv_header_sign); header_offset != -1 { + front_buf = buf[header_offset : header_offset+flv_header_size+previou_tag_size] } var ( - sign = 0x00 + sign = 0x00 keyframe_num = -1 - tag_num = 0 + tag_num = 0 ) - defer func(){ + defer func() { if sign != 0x07 { front_buf = []byte{} } @@ -434,74 +448,76 @@ func Seach_stream_tag(buf []byte)(front_buf []byte, keyframe[][]byte,err error){ } }() - for buf_offset:=0;buf_offset+tag_header_size len(buf) { err = errors.New(`reach end when get tag header`) // fmt.Printf("last %x\n",buf[tag_offset:tag_offset+tag_header_size]) - return//buf end + return //buf end } - streamid := int(F.Btoi32([]byte{0x00,buf[tag_offset+8],buf[tag_offset+9],buf[tag_offset+10]},0)) + streamid := int(F.Btoi32([]byte{0x00, buf[tag_offset+8], buf[tag_offset+9], buf[tag_offset+10]}, 0)) if streamid != 0 { buf_offset = tag_offset + 1 // fmt.Printf("streamid error %x\n",buf[tag_offset:tag_offset+tag_header_size]) - continue//streamid error + continue //streamid error } - tag_size := int(F.Btoi32([]byte{0x00,buf[tag_offset+1],buf[tag_offset+2],buf[tag_offset+3]},0)) + tag_size := int(F.Btoi32([]byte{0x00, buf[tag_offset+1], buf[tag_offset+2], buf[tag_offset+3]}, 0)) if tag_offset+tag_header_size+tag_size+previou_tag_size > len(buf) { err = errors.New(`reach end when get tag body`) // fmt.Printf("last %x\n",buf[tag_offset:tag_offset+tag_header_size]) - return//buf end + return //buf end } if tag_size == 0 { buf_offset = tag_offset + 1 // fmt.Printf("tag_size error %x\n",buf[tag_offset:tag_offset+tag_header_size]) - continue//tag_size error + continue //tag_size error } - tag_size_check := int(F.Btoi32(buf[tag_offset+tag_header_size+tag_size:tag_offset+tag_header_size+tag_size+previou_tag_size],0)) - if tag_num + tag_size_check == 0 {tag_size_check = tag_size+tag_header_size} + tag_size_check := int(F.Btoi32(buf[tag_offset+tag_header_size+tag_size:tag_offset+tag_header_size+tag_size+previou_tag_size], 0)) + if tag_num+tag_size_check == 0 { + tag_size_check = tag_size + tag_header_size + } if tag_size_check != tag_size+tag_header_size { buf_offset = tag_offset + 1 // fmt.Printf("tag_size_check error %x\n",buf[tag_offset:tag_offset+tag_header_size]) - continue//tag_size_check error + continue //tag_size_check error } - time_stamp := int(F.Btoi32([]byte{buf[tag_offset+7], buf[tag_offset+4], buf[tag_offset+5], buf[tag_offset+6]},0)) - + time_stamp := int(F.Btoi32([]byte{buf[tag_offset+7], buf[tag_offset+4], buf[tag_offset+5], buf[tag_offset+6]}, 0)) + // fmt.Printf("%x\n",buf[tag_offset:tag_offset+tag_header_size]) tag_num += 1 if time_stamp == 0 { if len(front_buf) != 0 { - if (buf[tag_offset] == video_tag) && (sign & 0x04 == 0x00) { + if (buf[tag_offset] == video_tag) && (sign&0x04 == 0x00) { sign |= 0x04 front_buf = append(front_buf, buf[tag_offset:tag_offset+tag_size_check+previou_tag_size]...) - } else if (buf[tag_offset] == audio_tag) && (sign & 0x02 == 0x00) { + } else if (buf[tag_offset] == audio_tag) && (sign&0x02 == 0x00) { sign |= 0x02 front_buf = append(front_buf, buf[tag_offset:tag_offset+tag_size_check+previou_tag_size]...) - } else if (buf[tag_offset] == script_tag) && (sign & 0x01 == 0x00) { + } else if (buf[tag_offset] == script_tag) && (sign&0x01 == 0x00) { sign |= 0x01 front_buf = append(front_buf, buf[tag_offset:tag_offset+tag_size_check+previou_tag_size]...) } } - buf_offset = tag_offset+tag_size_check+previou_tag_size + buf_offset = tag_offset + tag_size_check + previou_tag_size continue } - + if buf[tag_offset] == video_tag { - if buf[tag_offset+11] & 0xf0 == 0x10 {//key frame + if buf[tag_offset+11]&0xf0 == 0x10 { //key frame keyframe_num += 1 - keyframe = append(keyframe,[]byte{}) + keyframe = append(keyframe, []byte{}) } if keyframe_num >= 0 { @@ -511,153 +527,160 @@ func Seach_stream_tag(buf []byte)(front_buf []byte, keyframe[][]byte,err error){ if keyframe_num >= 0 { keyframe[keyframe_num] = append(keyframe[keyframe_num], buf[tag_offset:tag_offset+tag_size_check+previou_tag_size]...) } - } else {;} + } else { + } - buf_offset = tag_offset+tag_size_check+previou_tag_size + buf_offset = tag_offset + tag_size_check + previou_tag_size } - + return } //same as Seach_stream_tag but faster -func Seach_keyframe_tag(buf []byte)(front_buf []byte, keyframe[][]byte,err error){ +func Seach_keyframe_tag(buf []byte) (front_buf []byte, keyframe [][]byte, err error) { var ( sign = 0x00 // keyframe_num = -1 - tag_num = 0 + tag_num = 0 buf_offset = 0 ) - defer func(){ + defer func() { if sign != 0x07 { front_buf = []byte{} } }() //front_buf - if header_offset := bytes.Index(buf,flv_header_sign);header_offset != -1 { - front_buf = buf[header_offset:header_offset+flv_header_size+previou_tag_size] + if header_offset := bytes.Index(buf, flv_header_sign); header_offset != -1 { + front_buf = buf[header_offset : header_offset+flv_header_size+previou_tag_size] - for ;buf_offset+tag_header_size len(buf) { err = errors.New(`reach end when get tag header`) // fmt.Printf("last %x\n",buf[tag_offset:tag_offset+tag_header_size]) - return//buf end + return //buf end } - - if buf[tag_offset+8] | buf[tag_offset+9] | buf[tag_offset+10] != 0 { + + if buf[tag_offset+8]|buf[tag_offset+9]|buf[tag_offset+10] != 0 { buf_offset = tag_offset + 1 // fmt.Printf("streamid error %x\n",buf[tag_offset:tag_offset+tag_header_size]) - continue//streamid error + continue //streamid error } - - tag_size := int(F.Btoi32([]byte{0x00,buf[tag_offset+1],buf[tag_offset+2],buf[tag_offset+3]},0)) + + tag_size := int(F.Btoi32([]byte{0x00, buf[tag_offset+1], buf[tag_offset+2], buf[tag_offset+3]}, 0)) if tag_offset+tag_header_size+tag_size+previou_tag_size > len(buf) { err = errors.New(`reach end when get tag body`) // fmt.Printf("last %x\n",buf[tag_offset:tag_offset+tag_header_size]) - return//buf end + return //buf end } if tag_size == 0 { buf_offset = tag_offset + 1 // fmt.Printf("tag_size error %x\n",buf[tag_offset:tag_offset+tag_header_size]) - continue//tag_size error + continue //tag_size error + } + + tag_size_check := int(F.Btoi32(buf[tag_offset+tag_header_size+tag_size:tag_offset+tag_header_size+tag_size+previou_tag_size], 0)) + if tag_num+tag_size_check == 0 { + tag_size_check = tag_size + tag_header_size } - - tag_size_check := int(F.Btoi32(buf[tag_offset+tag_header_size+tag_size:tag_offset+tag_header_size+tag_size+previou_tag_size],0)) - if tag_num + tag_size_check == 0 {tag_size_check = tag_size+tag_header_size} if tag_size_check != tag_size+tag_header_size { buf_offset = tag_offset + 1 // fmt.Printf("tag_size_check error %x\n",buf[tag_offset:tag_offset+tag_header_size]) - continue//tag_size_check error + continue //tag_size_check error } - + tag_num += 1 - - if buf[tag_offset+7] | buf[tag_offset+4] | buf[tag_offset+5] | buf[tag_offset+6] == 0 { + + if buf[tag_offset+7]|buf[tag_offset+4]|buf[tag_offset+5]|buf[tag_offset+6] == 0 { if len(front_buf) != 0 { - if (buf[tag_offset] == video_tag) && (sign & 0x04 == 0x00) { + if (buf[tag_offset] == video_tag) && (sign&0x04 == 0x00) { sign |= 0x04 front_buf = append(front_buf, buf[tag_offset:tag_offset+tag_size_check+previou_tag_size]...) - } else if (buf[tag_offset] == audio_tag) && (sign & 0x02 == 0x00) { + } else if (buf[tag_offset] == audio_tag) && (sign&0x02 == 0x00) { sign |= 0x02 front_buf = append(front_buf, buf[tag_offset:tag_offset+tag_size_check+previou_tag_size]...) - } else if (buf[tag_offset] == script_tag) && (sign & 0x01 == 0x00) { + } else if (buf[tag_offset] == script_tag) && (sign&0x01 == 0x00) { sign |= 0x01 front_buf = append(front_buf, buf[tag_offset:tag_offset+tag_size_check+previou_tag_size]...) } } - buf_offset = tag_offset+tag_size_check+previou_tag_size + buf_offset = tag_offset + tag_size_check + previou_tag_size + } + if sign == 0x07 { + break } - if sign == 0x07 {break} } } //keyframe var last_keyframe_offset int - for ;buf_offset+tag_header_size len(buf) { err = errors.New(`reach end when get tag header`) // fmt.Printf("last %x\n",buf[tag_offset:tag_offset+tag_header_size]) - return//buf end + return //buf end } - if buf[tag_offset+8] | buf[tag_offset+9] | buf[tag_offset+10] != 0 { + if buf[tag_offset+8]|buf[tag_offset+9]|buf[tag_offset+10] != 0 { buf_offset = tag_offset + 1 // fmt.Printf("streamid error %x\n",buf[tag_offset:tag_offset+tag_header_size]) - continue//streamid error + continue //streamid error } - tag_size := int(F.Btoi32([]byte{0x00,buf[tag_offset+1],buf[tag_offset+2],buf[tag_offset+3]},0)) + tag_size := int(F.Btoi32([]byte{0x00, buf[tag_offset+1], buf[tag_offset+2], buf[tag_offset+3]}, 0)) if tag_offset+tag_header_size+tag_size+previou_tag_size > len(buf) { err = errors.New(`reach end when get tag body`) // fmt.Printf("last %x\n",buf[tag_offset:tag_offset+tag_header_size]) - return//buf end + return //buf end } if tag_size == 0 { buf_offset = tag_offset + 1 // fmt.Printf("tag_size error %x\n",buf[tag_offset:tag_offset+tag_header_size]) - continue//tag_size error + continue //tag_size error } - tag_size_check := int(F.Btoi32(buf[tag_offset+tag_header_size+tag_size:tag_offset+tag_header_size+tag_size+previou_tag_size],0)) - if tag_num + tag_size_check == 0 {tag_size_check = tag_size+tag_header_size} + tag_size_check := int(F.Btoi32(buf[tag_offset+tag_header_size+tag_size:tag_offset+tag_header_size+tag_size+previou_tag_size], 0)) + if tag_num+tag_size_check == 0 { + tag_size_check = tag_size + tag_header_size + } if tag_size_check != tag_size+tag_header_size { buf_offset = tag_offset + 1 // fmt.Printf("tag_size_check error %x\n",buf[tag_offset:tag_offset+tag_header_size]) - continue//tag_size_check error + continue //tag_size_check error } - + // fmt.Printf("%x\n",buf[tag_offset:tag_offset+tag_header_size]) tag_num += 1 - + if buf[tag_offset] == video_tag { - if buf[tag_offset+11] & 0xf0 == 0x10 {//key frame + if buf[tag_offset+11]&0xf0 == 0x10 { //key frame if last_keyframe_offset != 0 { - keyframe = append(keyframe,buf[last_keyframe_offset:tag_offset]) + keyframe = append(keyframe, buf[last_keyframe_offset:tag_offset]) } last_keyframe_offset = tag_offset } } - buf_offset = tag_offset+tag_size_check+previou_tag_size + buf_offset = tag_offset + tag_size_check + previou_tag_size } return @@ -665,9 +688,11 @@ func Seach_keyframe_tag(buf []byte)(front_buf []byte, keyframe[][]byte,err error //this fuction merge two stream and return the merge buffer,which has the newest frame. //once len(merge_buf) isn't 0,old_buf can be drop and new_buf can be used from now on.or it's still need to keep buf until find the same tag. -func Merge_stream(keyframe_lists [][][]byte,last_keyframe_timestramp int)(keyframe_timestamp int,merge_buf []byte,merged int){ +func Merge_stream(keyframe_lists [][][]byte, last_keyframe_timestramp int) (keyframe_timestamp int, merge_buf []byte, merged int) { - if len(keyframe_lists) == 0 {return} + if len(keyframe_lists) == 0 { + return + } // var keyframe_lists [][][]byte // for i:=0;i len(buf[0]) { err = errors.New(`reach end when get tag header`) // fmt.Printf("last %x\n",buf[tag_offset:tag_offset+tag_header_size]) - return//buf end + return //buf end } - - if buf[0][tag_offset+8] | buf[0][tag_offset+9] | buf[0][tag_offset+10] != 0 { + + if buf[0][tag_offset+8]|buf[0][tag_offset+9]|buf[0][tag_offset+10] != 0 { buf_offset = tag_offset + 1 // fmt.Printf("streamid error %x\n",buf[tag_offset:tag_offset+tag_header_size]) - continue//streamid error + continue //streamid error } - - tag_size := int(F.Btoi32([]byte{0x00,buf[0][tag_offset+1],buf[0][tag_offset+2],buf[0][tag_offset+3]},0)) + + tag_size := int(F.Btoi32([]byte{0x00, buf[0][tag_offset+1], buf[0][tag_offset+2], buf[0][tag_offset+3]}, 0)) if tag_offset+tag_header_size+tag_size+previou_tag_size > len(buf[0]) { err = errors.New(`reach end when get tag body`) // fmt.Printf("last %x\n",buf[tag_offset:tag_offset+tag_header_size]) - return//buf end + return //buf end } if tag_size == 0 { buf_offset = tag_offset + 1 // fmt.Printf("tag_size error %x\n",buf[tag_offset:tag_offset+tag_header_size]) - continue//tag_size error + continue //tag_size error + } + + tag_size_check := int(F.Btoi32(buf[0][tag_offset+tag_header_size+tag_size:tag_offset+tag_header_size+tag_size+previou_tag_size], 0)) + if tag_num+tag_size_check == 0 { + tag_size_check = tag_size + tag_header_size } - - tag_size_check := int(F.Btoi32(buf[0][tag_offset+tag_header_size+tag_size:tag_offset+tag_header_size+tag_size+previou_tag_size],0)) - if tag_num + tag_size_check == 0 {tag_size_check = tag_size+tag_header_size} if tag_size_check != tag_size+tag_header_size { buf_offset = tag_offset + 1 // fmt.Printf("tag_size_check error %x\n",buf[tag_offset:tag_offset+tag_header_size]) - continue//tag_size_check error + continue //tag_size_check error } - + tag_num += 1 - - time_stamp := int(F.Btoi32([]byte{buf[0][tag_offset+7], buf[0][tag_offset+4], buf[0][tag_offset+5], buf[0][tag_offset+6]},0)) - + + time_stamp := int(F.Btoi32([]byte{buf[0][tag_offset+7], buf[0][tag_offset+4], buf[0][tag_offset+5], buf[0][tag_offset+6]}, 0)) + // if tag_num == 1 && last_keyframe_timestamp != 0 { // diff_time = last_keyframe_timestamp + 3000 - time_stamp // fmt.Printf("时间戳调整 last:%d now:%d diff:%d\n",last_keyframe_timestamp,time_stamp,diff_time) - - if buf[0][tag_offset] == video_tag && buf[0][tag_offset+11] & 0xf0 == 0x10{ - first_t = time_stamp - } else { - last_t = time_stamp - } + + if buf[0][tag_offset] == video_tag && buf[0][tag_offset+11]&0xf0 == 0x10 { + first_t = time_stamp + } else { + last_t = time_stamp + } // } - - buf_offset = tag_offset+tag_size_check+previou_tag_size + + buf_offset = tag_offset + tag_size_check + previou_tag_size + } + for keyframe_interval = 100; keyframe_interval <= last_t-first_t; keyframe_interval += 100 { } - for keyframe_interval=100;keyframe_interval<=last_t-first_t;keyframe_interval+=100 {} } tag_num = 0 base_keyframe_time = 0 - for i:=0;i len(buf[i]) { err = errors.New(`reach end when get tag header`) // fmt.Printf("last %x\n",buf[tag_offset:tag_offset+tag_header_size]) - return//buf end + return //buf end } - - if buf[i][tag_offset+8] | buf[i][tag_offset+9] | buf[i][tag_offset+10] != 0 { + + if buf[i][tag_offset+8]|buf[i][tag_offset+9]|buf[i][tag_offset+10] != 0 { buf_offset = tag_offset + 1 // fmt.Printf("streamid error %x\n",buf[tag_offset:tag_offset+tag_header_size]) - continue//streamid error + continue //streamid error } - - tag_size := int(F.Btoi32([]byte{0x00,buf[i][tag_offset+1],buf[i][tag_offset+2],buf[i][tag_offset+3]},0)) + + tag_size := int(F.Btoi32([]byte{0x00, buf[i][tag_offset+1], buf[i][tag_offset+2], buf[i][tag_offset+3]}, 0)) if tag_offset+tag_header_size+tag_size+previou_tag_size > len(buf[i]) { err = errors.New(`reach end when get tag body`) // fmt.Printf("last %x\n",buf[tag_offset:tag_offset+tag_header_size]) - return//buf end + return //buf end } if tag_size == 0 { buf_offset = tag_offset + 1 // fmt.Printf("tag_size error %x\n",buf[tag_offset:tag_offset+tag_header_size]) - continue//tag_size error + continue //tag_size error + } + + tag_size_check := int(F.Btoi32(buf[i][tag_offset+tag_header_size+tag_size:tag_offset+tag_header_size+tag_size+previou_tag_size], 0)) + if tag_num+tag_size_check == 0 { + tag_size_check = tag_size + tag_header_size } - - tag_size_check := int(F.Btoi32(buf[i][tag_offset+tag_header_size+tag_size:tag_offset+tag_header_size+tag_size+previou_tag_size],0)) - if tag_num + tag_size_check == 0 {tag_size_check = tag_size+tag_header_size} if tag_size_check != tag_size+tag_header_size { buf_offset = tag_offset + 1 // fmt.Printf("tag_size_check error %x\n",buf[tag_offset:tag_offset+tag_header_size]) - continue//tag_size_check error + continue //tag_size_check error } - + tag_num += 1 - - time_stamp := int(F.Btoi32([]byte{buf[i][tag_offset+7], buf[i][tag_offset+4], buf[i][tag_offset+5], buf[i][tag_offset+6]},0)) - + + time_stamp := int(F.Btoi32([]byte{buf[i][tag_offset+7], buf[i][tag_offset+4], buf[i][tag_offset+5], buf[i][tag_offset+6]}, 0)) + // if tag_num == 1 && last_keyframe_timestamp != 0 { // diff_time = last_keyframe_timestamp + 3000 - time_stamp // fmt.Printf("时间戳调整 last:%d now:%d diff:%d\n",last_keyframe_timestamp,time_stamp,diff_time) - if buf[i][tag_offset] == video_tag && buf[i][tag_offset+11] & 0xf0 == 0x10{ - // if {//key frame - base_keyframe_time = time_stamp - time_stamp = keyframe_timestamp - last_keyframe_timestamp = keyframe_timestamp - // fmt.Printf("当前关键帧时间戳 %d %d=>%d\n",last_keyframe_timestamp,base_keyframe_time,keyframe_timestamp) - // } - } else { - time_stamp += keyframe_timestamp-base_keyframe_time - } + if buf[i][tag_offset] == video_tag && buf[i][tag_offset+11]&0xf0 == 0x10 { + // if {//key frame + base_keyframe_time = time_stamp + time_stamp = keyframe_timestamp + last_keyframe_timestamp = keyframe_timestamp + // fmt.Printf("当前关键帧时间戳 %d %d=>%d\n",last_keyframe_timestamp,base_keyframe_time,keyframe_timestamp) + // } + } else { + time_stamp += keyframe_timestamp - base_keyframe_time + } // } time_stamp_byte := F.Itob32(int32(time_stamp)) - + buf[i][tag_offset+7] = time_stamp_byte[0] buf[i][tag_offset+4] = time_stamp_byte[1] buf[i][tag_offset+5] = time_stamp_byte[2] buf[i][tag_offset+6] = time_stamp_byte[3] - - buf_offset = tag_offset+tag_size_check+previou_tag_size + + buf_offset = tag_offset + tag_size_check + previou_tag_size } } return -} \ No newline at end of file +} diff --git a/Reply/steam/stream.go b/Reply/steam/stream.go index 5269aa4..c2a5751 100644 --- a/Reply/steam/stream.go +++ b/Reply/steam/stream.go @@ -25,25 +25,25 @@ type Stream_Config struct { func (t *Stream) LoadConfig() { //读取配置 - if path, ok := c.K_v.LoadV("直播流保存位置").(string); ok { + if path, ok := c.C.K_v.LoadV("直播流保存位置").(string); ok { if path, err := filepath.Abs(path); err == nil { t.config.save_path = path + "/" } } - if v, ok := c.K_v.LoadV(`直播hls流缓冲`).(float64); ok && v > 0 { + if v, ok := c.C.K_v.LoadV(`直播hls流缓冲`).(float64); ok && v > 0 { t.config.bufsize = int(v) } - if v, ok := c.K_v.LoadV(`直播hls流均衡`).(bool); ok { + if v, ok := c.C.K_v.LoadV(`直播hls流均衡`).(bool); ok { t.config.banlance_host = v } - if v, ok := c.K_v.LoadV(`直播流清晰度`).(int); ok { + if v, ok := c.C.K_v.LoadV(`直播流清晰度`).(int); ok { t.config.want_qn = v } - if v, ok := c.K_v.LoadV(`直播流类型`).(string); ok { + if v, ok := c.C.K_v.LoadV(`直播流类型`).(string); ok { t.config.want_type = v } } func (t *Stream) Start() { - t.log = c.Log.Base(`直播流保存`) + t.log = c.C.Log.Base(`直播流保存`) } diff --git a/Reply/tts.go b/Reply/tts.go index 18331d4..c4006c1 100644 --- a/Reply/tts.go +++ b/Reply/tts.go @@ -37,7 +37,7 @@ var tts_List = make(chan string, 20) var tts_limit = limit.New(1, 5000, 15000) //频率限制1次/5s,最大等待时间15s -var tts_log = c.Log.Base_add(`TTS`) +var tts_log = c.C.Log.Base_add(`TTS`) var ( tts_ser = "baidu" @@ -53,20 +53,20 @@ var ( func init() { { //tts配置 - if v, ok := c.K_v.LoadV(`TTS_总开关`).(bool); ok && !v { + if v, ok := c.C.K_v.LoadV(`TTS_总开关`).(bool); ok && !v { return } - if v, ok := c.K_v.LoadV(`TTS_使用程序路径`).(string); ok && v != `` { + if v, ok := c.C.K_v.LoadV(`TTS_使用程序路径`).(string); ok && v != `` { tts_prog = v } else { tts_log.L(`E: `, `TTS_使用程序路径不是字符串或为空`) } - if v, ok := c.K_v.LoadV(`TTS_使用程序参数`).(string); ok && v != `` { + if v, ok := c.C.K_v.LoadV(`TTS_使用程序参数`).(string); ok && v != `` { tts_prog_set = v } else { tts_log.L(`E: `, `TTS_使用程序参数不是字符串`) } - if v, ok := c.K_v.LoadV(`TTS_服务器`).(string); ok && v != "" { + if v, ok := c.C.K_v.LoadV(`TTS_服务器`).(string); ok && v != "" { if _, ok := tts_ser_map[v]; ok { tts_ser = v } else { @@ -107,7 +107,7 @@ func init() { //消息队列接收tts类消息,并传送到TTS朗读 //使用带tag的消息队列在功能间传递消息 - c.Danmu_Main_mq.Pull_tag(msgq.FuncMap{ + c.C.Danmu_Main_mq.Pull_tag(msgq.FuncMap{ `tts`: func(data interface{}) bool { //tts d, _ := data.(Danmu_mq_t) if s, ok := tts_setting_string[d.uid]; ok && len(d.m) != 0 && s != "" { @@ -190,7 +190,7 @@ func baidu(msg string) error { Timeout: 3 * 1000, Retry: 1, SleepTime: 5000, - Proxy: c.Proxy, + Proxy: c.C.Proxy, }); err != nil { return err } @@ -204,10 +204,10 @@ var ( ) func init() { - if v, ok := c.K_v.LoadV(`TTS_服务器_youdaoId`).(string); ok && v != `` { + if v, ok := c.C.K_v.LoadV(`TTS_服务器_youdaoId`).(string); ok && v != `` { youdaoId = v } - if v, ok := c.K_v.LoadV(`TTS_服务器_youdaoKey`).(string); ok && v != `` { + if v, ok := c.C.K_v.LoadV(`TTS_服务器_youdaoKey`).(string); ok && v != `` { youdaoappKey = v } if tts_ser == `youdao` && (youdaoId == `` || youdaoappKey == ``) { @@ -246,7 +246,7 @@ func youdao(msg string) error { Timeout: 3 * 1000, Retry: 1, SleepTime: 5000, - Proxy: c.Proxy, + Proxy: c.C.Proxy, }); err != nil { return err } @@ -275,16 +275,16 @@ var ( ) func init() { - if v, ok := c.K_v.LoadV(`TTS_服务器_xfId`).(string); ok && v != `` { + if v, ok := c.C.K_v.LoadV(`TTS_服务器_xfId`).(string); ok && v != `` { xfId = v } - if v, ok := c.K_v.LoadV(`TTS_服务器_xfKey`).(string); ok && v != `` { + if v, ok := c.C.K_v.LoadV(`TTS_服务器_xfKey`).(string); ok && v != `` { xfKey = v } - if v, ok := c.K_v.LoadV(`TTS_服务器_xfSecret`).(string); ok && v != `` { + if v, ok := c.C.K_v.LoadV(`TTS_服务器_xfSecret`).(string); ok && v != `` { xfSecret = v } - if v, ok := c.K_v.LoadV(`TTS_服务器_xfVoice`).(string); ok && v != `` { + if v, ok := c.C.K_v.LoadV(`TTS_服务器_xfVoice`).(string); ok && v != `` { if _, ok := xfVmap[v]; ok || v == `random` { xfVoice = v } else { @@ -348,7 +348,7 @@ func init() { xfwsClient = ws.New_client(ws.Client{ Url: wsUrl, - Proxy: c.Proxy, + Proxy: c.C.Proxy, Header: map[string]string{ `User-Agent`: `Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0`, `Accept`: `*/*`, diff --git a/Send/Send.go b/Send/Send.go index 8299aca..9f75d78 100644 --- a/Send/Send.go +++ b/Send/Send.go @@ -1,15 +1,15 @@ package send import ( - "strconv" "encoding/json" "net/url" + "strconv" c "github.com/qydysky/bili_danmu/CV" p "github.com/qydysky/part" - reqf "github.com/qydysky/part/reqf" limit "github.com/qydysky/part/limit" + reqf "github.com/qydysky/part/reqf" ) //每5s一个令牌,最多等20秒 @@ -18,63 +18,68 @@ var danmu_s_limit = limit.New(1, 5000, 20000) //弹幕发送 func Danmu_s(msg string, roomid int) { //等待令牌时阻塞,超时返回true - if danmu_s_limit.TO() {return} + if danmu_s_limit.TO() { + return + } - l := c.Log.Base("弹幕发送") + l := c.C.Log.Base("弹幕发送") - if msg == "" || roomid == 0{ - l.L(`E: `,"输入参数不足") + if msg == "" || roomid == 0 { + l.L(`E: `, "输入参数不足") return } - csrf,_ := c.Cookie.LoadV(`bili_jct`).(string) - if csrf == `` {l.L(`E: `,"Cookie错误,无bili_jct=");return} + csrf, _ := c.C.Cookie.LoadV(`bili_jct`).(string) + if csrf == `` { + l.L(`E: `, "Cookie错误,无bili_jct=") + return + } Cookie := make(map[string]string) - c.Cookie.Range(func(k,v interface{})(bool){ + c.C.Cookie.Range(func(k, v interface{}) bool { Cookie[k.(string)] = v.(string) return true }) PostStr := `color=16777215&fontsize=25&mode=1&msg=` + msg + `&rnd=` + strconv.Itoa(int(p.Sys().GetSTime())) + `&roomid=` + strconv.Itoa(roomid) + `&bubble=0&csrf_token=` + csrf + `&csrf=` + csrf - l.L(`I: `,"发送", msg, "至", roomid) + l.L(`I: `, "发送", msg, "至", roomid) r := reqf.New() err := r.Reqf(reqf.Rval{ - Url:"https://api.live.bilibili.com/msg/send", - PostStr:url.PathEscape(PostStr), - Retry:2, - Timeout:5*1000, - Proxy:c.Proxy, - Header:map[string]string{ - `Host`: `api.live.bilibili.com`, - `User-Agent`: `Mozilla/5.0 (X11; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0`, - `Accept`: `application/json, text/javascript, */*; q=0.01`, + Url: "https://api.live.bilibili.com/msg/send", + PostStr: url.PathEscape(PostStr), + Retry: 2, + Timeout: 5 * 1000, + Proxy: c.C.Proxy, + Header: map[string]string{ + `Host`: `api.live.bilibili.com`, + `User-Agent`: `Mozilla/5.0 (X11; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0`, + `Accept`: `application/json, text/javascript, */*; q=0.01`, `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`, - `Content-Type`: `application/x-www-form-urlencoded; charset=UTF-8`, - `Origin`: `https://live.bilibili.com`, - `Connection`: `keep-alive`, - `Pragma`: `no-cache`, - `Cache-Control`: `no-cache`, - `Referer`:"https://live.bilibili.com/" + strconv.Itoa(roomid), - `Cookie`:reqf.Map_2_Cookies_String(Cookie), + `Content-Type`: `application/x-www-form-urlencoded; charset=UTF-8`, + `Origin`: `https://live.bilibili.com`, + `Connection`: `keep-alive`, + `Pragma`: `no-cache`, + `Cache-Control`: `no-cache`, + `Referer`: "https://live.bilibili.com/" + strconv.Itoa(roomid), + `Cookie`: reqf.Map_2_Cookies_String(Cookie), }, }) if err != nil { - l.L(`E: `,err) + l.L(`E: `, err) return } - - var res struct{ - Code int `json:"code"` + + var res struct { + Code int `json:"code"` Message string `json:"message"` } - if e := json.Unmarshal(r.Respon, &res);e != nil{ - l.L(`E: `,e) + if e := json.Unmarshal(r.Respon, &res); e != nil { + l.L(`E: `, e) } if res.Code != 0 { - l.L(`E: `, `产生错误:`,res.Code, res.Message) + l.L(`E: `, `产生错误:`, res.Code, res.Message) } -} \ No newline at end of file +} diff --git a/Send/Send_gift.go b/Send/Send_gift.go index 733e242..489edc0 100644 --- a/Send/Send_gift.go +++ b/Send/Send_gift.go @@ -1,98 +1,106 @@ package send import ( - "time" - "net/url" "encoding/json" + "net/url" "strconv" + "time" c "github.com/qydysky/bili_danmu/CV" - reqf "github.com/qydysky/part/reqf" limit "github.com/qydysky/part/limit" + reqf "github.com/qydysky/part/reqf" ) //每2s一个令牌,最多等10秒 var gift_limit = limit.New(1, 2000, 10000) -func Send_gift(gift_id,bag_id,gift_num int) { - log := c.Log.Base_add(`发送礼物`) +func Send_gift(gift_id, bag_id, gift_num int) { + log := c.C.Log.Base_add(`发送礼物`) - if gift_limit.TO() {log.L(`W: `,"超时");return} + if gift_limit.TO() { + log.L(`W: `, "超时") + return + } - if c.UpUid == 0 {log.L(`W: `,"还未获取到Up主uid");return} + if c.C.UpUid == 0 { + log.L(`W: `, "还未获取到Up主uid") + return + } - {//发送请求(银瓜子礼物) - csrf,_ := c.Cookie.LoadV(`bili_jct`).(string) - if csrf == `` {log.L(`E: `,"Cookie错误,无bili_jct=");return} + { //发送请求(银瓜子礼物) + csrf, _ := c.C.Cookie.LoadV(`bili_jct`).(string) + if csrf == `` { + log.L(`E: `, "Cookie错误,无bili_jct=") + return + } - var sendStr = - `uid=`+strconv.Itoa(c.Uid)+`&`+ - `gift_id=`+strconv.Itoa(gift_id)+`&`+ - `ruid=`+strconv.Itoa(c.UpUid)+`&`+ - `send_ruid=0&`+ - `gift_num=`+strconv.Itoa(gift_num)+`&`+ - `bag_id=`+strconv.Itoa(bag_id)+`&`+ - `platform=pc&`+ - `biz_code=live&`+ - `biz_id=`+strconv.Itoa(c.Roomid)+`&`+ - `rnd=`+strconv.Itoa(int(time.Now().Unix()))+`&`+ - `storm_beat_id=0&`+ - `metadata=&`+ - `price=0&`+ - `csrf_token=`+csrf+`&`+ - `csrf=`+csrf+`&`+ - `visit_id=` + var sendStr = `uid=` + strconv.Itoa(c.C.Uid) + `&` + + `gift_id=` + strconv.Itoa(gift_id) + `&` + + `ruid=` + strconv.Itoa(c.C.UpUid) + `&` + + `send_ruid=0&` + + `gift_num=` + strconv.Itoa(gift_num) + `&` + + `bag_id=` + strconv.Itoa(bag_id) + `&` + + `platform=pc&` + + `biz_code=live&` + + `biz_id=` + strconv.Itoa(c.C.Roomid) + `&` + + `rnd=` + strconv.Itoa(int(time.Now().Unix())) + `&` + + `storm_beat_id=0&` + + `metadata=&` + + `price=0&` + + `csrf_token=` + csrf + `&` + + `csrf=` + csrf + `&` + + `visit_id=` Cookie := make(map[string]string) - c.Cookie.Range(func(k,v interface{})(bool){ + c.C.Cookie.Range(func(k, v interface{}) bool { Cookie[k.(string)] = v.(string) return true }) - + req := reqf.New() - if e:= req.Reqf(reqf.Rval{ - Url:`https://api.live.bilibili.com/gift/v2/live/bag_send`, - PostStr:url.PathEscape(sendStr), - Timeout:10*1000, - Proxy:c.Proxy, - Header:map[string]string{ - `Host`: `api.vc.bilibili.com`, - `User-Agent`: `Mozilla/5.0 (X11; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0`, - `Accept`: `application/json, text/javascript, */*; q=0.01`, + if e := req.Reqf(reqf.Rval{ + Url: `https://api.live.bilibili.com/gift/v2/live/bag_send`, + PostStr: url.PathEscape(sendStr), + Timeout: 10 * 1000, + Proxy: c.C.Proxy, + Header: map[string]string{ + `Host`: `api.vc.bilibili.com`, + `User-Agent`: `Mozilla/5.0 (X11; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0`, + `Accept`: `application/json, text/javascript, */*; q=0.01`, `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`, - `Content-Type`: `application/x-www-form-urlencoded; charset=UTF-8`, - `Origin`: `https://message.bilibili.com`, - `Connection`: `keep-alive`, - `Pragma`: `no-cache`, - `Cache-Control`: `no-cache`, - `Referer`:"https://message.bilibili.com", - `Cookie`:reqf.Map_2_Cookies_String(Cookie), + `Content-Type`: `application/x-www-form-urlencoded; charset=UTF-8`, + `Origin`: `https://message.bilibili.com`, + `Connection`: `keep-alive`, + `Pragma`: `no-cache`, + `Cache-Control`: `no-cache`, + `Referer`: "https://message.bilibili.com", + `Cookie`: reqf.Map_2_Cookies_String(Cookie), }, - });e != nil { - log.L(`E: `,e) + }); e != nil { + log.L(`E: `, e) return } - - var res struct{ - Code int `json:"code"` + + var res struct { + Code int `json:"code"` Message string `json:"message"` - Data struct{ + Data struct { Gift_name string `json:"gift_name"` - Gift_num int `json:"gift_num"` + Gift_num int `json:"gift_num"` } `json:"data"` } - if e := json.Unmarshal(req.Respon, &res);e != nil { - log.L(`E: `,e) + if e := json.Unmarshal(req.Respon, &res); e != nil { + log.L(`E: `, e) return } if res.Code != 0 { - log.L(`W: `,res.Message) + log.L(`W: `, res.Message) return } - log.L(`I: `,`给`,c.Roomid,`赠送了`,res.Data.Gift_num,`个`,res.Data.Gift_name) + log.L(`I: `, `给`, c.C.Roomid, `赠送了`, res.Data.Gift_num, `个`, res.Data.Gift_name) } } diff --git a/Send/Send_pm.go b/Send/Send_pm.go index 0728be6..5a9ef3d 100644 --- a/Send/Send_pm.go +++ b/Send/Send_pm.go @@ -1,15 +1,16 @@ package send - + import ( - "net/url" "errors" - "strings" + "net/url" "strconv" + "strings" + c "github.com/qydysky/bili_danmu/CV" p "github.com/qydysky/part" - reqf "github.com/qydysky/part/reqf" limit "github.com/qydysky/part/limit" + reqf "github.com/qydysky/part/reqf" uuid "github.com/gofrs/uuid" ) @@ -27,69 +28,73 @@ func Send_pm(uid int, msg string) error { return errors.New(`msg == "" || uid == 0`) } - log := c.Log.Base_add(`私信`) + log := c.C.Log.Base_add(`私信`) - if c.Uid == 0 { - log.L(`E: `,`client uid == 0`) + if c.C.Uid == 0 { + log.L(`E: `, `client uid == 0`) return errors.New(`client uid == 0`) - } else if c.Uid == uid { - log.L(`W: `,`不能发送给自己`) + } else if c.C.Uid == uid { + log.L(`W: `, `不能发送给自己`) return errors.New(`不能发送给自己`) } - csrf,_ := c.Cookie.LoadV(`bili_jct`).(string) - if csrf == `` {return errors.New("Cookie错误,无bili_jct=")} + csrf, _ := c.C.Cookie.LoadV(`bili_jct`).(string) + if csrf == `` { + return errors.New("Cookie错误,无bili_jct=") + } var new_uuid string { - if tmp_uuid,e := uuid.NewV4();e == nil { + if tmp_uuid, e := uuid.NewV4(); e == nil { new_uuid = tmp_uuid.String() } else { - log.L(`E: `,e) + log.L(`E: `, e) return e } } - if pm_limit.TO() {return errors.New("TO")} + if pm_limit.TO() { + return errors.New("TO") + } + + var send_str = `msg[sender_uid]=` + strconv.Itoa(c.C.Uid) + `&msg[receiver_id]=` + strconv.Itoa(uid) + `&msg[receiver_type]=1&msg[msg_type]=1&msg[msg_status]=0&msg[content]={"content":"` + msg + `"}&msg[timestamp]=` + strconv.Itoa(int(p.Sys().GetSTime())) + `&msg[new_face_version]=0&msg[dev_id]=` + strings.ToUpper(new_uuid) + `&from_firework=0&build=0&mobi_app=web&csrf_token=` + csrf + `&csrf=` + csrf - var send_str = `msg[sender_uid]=`+strconv.Itoa(c.Uid)+`&msg[receiver_id]=`+strconv.Itoa(uid)+`&msg[receiver_type]=1&msg[msg_type]=1&msg[msg_status]=0&msg[content]={"content":"`+msg+`"}&msg[timestamp]=`+strconv.Itoa(int(p.Sys().GetSTime()))+`&msg[new_face_version]=0&msg[dev_id]=`+strings.ToUpper(new_uuid)+`&from_firework=0&build=0&mobi_app=web&csrf_token=`+csrf+`&csrf=`+csrf - Cookie := make(map[string]string) - c.Cookie.Range(func(k,v interface{})(bool){ + c.C.Cookie.Range(func(k, v interface{}) bool { Cookie[k.(string)] = v.(string) return true }) - + req := reqf.New() - if e:= req.Reqf(reqf.Rval{ - Url:`https://api.vc.bilibili.com/web_im/v1/web_im/send_msg`, - PostStr:url.PathEscape(send_str), - Timeout:10*1000, - Proxy:c.Proxy, - Header:map[string]string{ - `Host`: `api.vc.bilibili.com`, - `User-Agent`: `Mozilla/5.0 (X11; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0`, - `Accept`: `application/json, text/javascript, */*; q=0.01`, + if e := req.Reqf(reqf.Rval{ + Url: `https://api.vc.bilibili.com/web_im/v1/web_im/send_msg`, + PostStr: url.PathEscape(send_str), + Timeout: 10 * 1000, + Proxy: c.C.Proxy, + Header: map[string]string{ + `Host`: `api.vc.bilibili.com`, + `User-Agent`: `Mozilla/5.0 (X11; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0`, + `Accept`: `application/json, text/javascript, */*; q=0.01`, `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`, - `Content-Type`: `application/x-www-form-urlencoded; charset=UTF-8`, - `Origin`: `https://message.bilibili.com`, - `Connection`: `keep-alive`, - `Pragma`: `no-cache`, - `Cache-Control`: `no-cache`, - `Referer`:"https://message.bilibili.com", - `Cookie`:reqf.Map_2_Cookies_String(Cookie), + `Content-Type`: `application/x-www-form-urlencoded; charset=UTF-8`, + `Origin`: `https://message.bilibili.com`, + `Connection`: `keep-alive`, + `Pragma`: `no-cache`, + `Cache-Control`: `no-cache`, + `Referer`: "https://message.bilibili.com", + `Cookie`: reqf.Map_2_Cookies_String(Cookie), }, - });e != nil { - log.L(`E: `,e) + }); e != nil { + log.L(`E: `, e) return e } - if code := p.Json().GetValFromS(string(req.Respon), "code");code == nil || code.(float64) != 0 { - log.L(`E: `,string(req.Respon)) + if code := p.Json().GetValFromS(string(req.Respon), "code"); code == nil || code.(float64) != 0 { + log.L(`E: `, string(req.Respon)) return errors.New(string(req.Respon)) } - log.L(`I: `,`发送私信给`,uid,`:`,msg) + log.L(`I: `, `发送私信给`, uid, `:`, msg) return nil -} \ No newline at end of file +} diff --git a/bili_danmu.go b/bili_danmu.go index ba31c6b..69d476f 100644 --- a/bili_danmu.go +++ b/bili_danmu.go @@ -1,48 +1,48 @@ package bili_danmu import ( - "fmt" "flag" - "time" + "fmt" "net/url" - "strconv" "os" "os/signal" - - reply "github.com/qydysky/bili_danmu/Reply" - send "github.com/qydysky/bili_danmu/Send" + "strconv" + "time" + c "github.com/qydysky/bili_danmu/CV" F "github.com/qydysky/bili_danmu/F" + reply "github.com/qydysky/bili_danmu/Reply" + send "github.com/qydysky/bili_danmu/Send" p "github.com/qydysky/part" - ws "github.com/qydysky/part/websocket" msgq "github.com/qydysky/part/msgq" reqf "github.com/qydysky/part/reqf" + ws "github.com/qydysky/part/websocket" ) func init() { - go func(){//日期变化 + go func() { //日期变化 var old = time.Now().Hour() for { - if now := time.Now().Hour();now == 0 && old != now { - c.Danmu_Main_mq.Push_tag(`new day`,nil) + if now := time.Now().Hour(); now == 0 && old != now { + c.C.Danmu_Main_mq.Push_tag(`new day`, nil) old = now } - time.Sleep(time.Second*time.Duration(100)) + time.Sleep(time.Second * time.Duration(100)) } }() } func Demo(roomid ...int) { - var danmulog = c.Log.Base(`bilidanmu Demo`) + var danmulog = c.C.Log.Base(`bilidanmu Demo`) defer danmulog.Block(1000) //ctrl+c退出 - interrupt := make(chan os.Signal,2) - go func(){ + interrupt := make(chan os.Signal, 2) + go func() { danmulog.L(`T: `, "两次ctrl+c强制退出") for len(interrupt) < 2 { - time.Sleep(time.Second*3) + time.Sleep(time.Second * 3) } danmulog.L(`I: `, "强制退出!").Block(1000) os.Exit(1) @@ -54,7 +54,7 @@ func Demo(roomid ...int) { var ( change_room_chan = make(chan struct{}) - flash_room_chan = make(chan struct{}) + flash_room_chan = make(chan struct{}) ) //-r 房间初始化 @@ -66,63 +66,65 @@ func Demo(roomid ...int) { //如果连接中断,则等待 F.KeepConnect() //获取cookie - F.Get(`Cookie`) + F.Get(&c.C).Get(`Cookie`) //获取LIVE_BUVID - F.Get(`LIVE_BUVID`) + F.Get(&c.C).Get(`LIVE_BUVID`) if room == 0 { - c.Log.Block(1000)//等待所有日志输出完毕 + c.C.Log.Block(1000) //等待所有日志输出完毕 fmt.Println("输入房间号或` live`获取正在直播的主播") } else { fmt.Print("房间号: ", strconv.Itoa(room), "\n") - if c.Roomid == 0 { - c.Roomid = room - go func(){change_room_chan <- struct{}{}}() + if c.C.Roomid == 0 { + c.C.Roomid = room + go func() { change_room_chan <- struct{}{} }() } } //命令行操作 切换房间 发送弹幕 go F.Cmd() //使用带tag的消息队列在功能间传递消息 - c.Danmu_Main_mq.Pull_tag(msgq.FuncMap{ - `flash_room`:func(data interface{})(bool){//房间重进 + c.C.Danmu_Main_mq.Pull_tag(msgq.FuncMap{ + `flash_room`: func(data interface{}) bool { //房间重进 select { - case flash_room_chan <- struct{}{}:; - default:; + case flash_room_chan <- struct{}{}: + default: } return false }, - `change_room`:func(data interface{})(bool){//房间改变 - c.Rev = 0.0 //营收 - c.Renqi = 1//人气置1 - c.GuardNum = 0//舰长数 - c.Note = ``//分区排行 - c.Uname = ``//主播id - c.Title = `` - c.Wearing_FansMedal = 0 - for len(change_room_chan) != 0 {<-change_room_chan} + `change_room`: func(data interface{}) bool { //房间改变 + c.C.Rev = 0.0 //营收 + c.C.Renqi = 1 //人气置1 + 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 + } change_room_chan <- struct{}{} return false }, - `c.Rev_add`:func(data interface{})(bool){//收入 - c.Rev += data.(float64) + `c.Rev_add`: func(data interface{}) bool { //收入 + c.C.Rev += data.(float64) return false }, - `c.Renqi`:func(data interface{})(bool){//人气更新 - if tmp,ok := data.(int);ok{ - c.Renqi = tmp + `c.Renqi`: func(data interface{}) bool { //人气更新 + if tmp, ok := data.(int); ok { + c.C.Renqi = tmp } return false }, - `gtk_close`:func(data interface{})(bool){//gtk关闭信号 + `gtk_close`: func(data interface{}) bool { //gtk关闭信号 interrupt <- os.Interrupt return false }, }) //单独,避免队列执行耗时block从而无法接收更多消息 - c.Danmu_Main_mq.Pull_tag(msgq.FuncMap{ - `pm`:func(data interface{})(bool){//私信 - if tmp,ok := data.(send.Pm_item);ok{ - send.Send_pm(tmp.Uid,tmp.Msg) + c.C.Danmu_Main_mq.Pull_tag(msgq.FuncMap{ + `pm`: func(data interface{}) bool { //私信 + if tmp, ok := data.(send.Pm_item); ok { + send.Send_pm(tmp.Uid, tmp.Msg) } return false }, @@ -133,9 +135,9 @@ func Demo(roomid ...int) { //捕获ctrl+c退出 signal.Notify(interrupt, os.Interrupt) //获取uid - F.Get(`Uid`) + F.Get(&c.C).Get(`Uid`) //兑换硬币 - F.Get(`Silver_2_coin`) + F.Get(&c.C).Get(`Silver_2_coin`) //每日签到 F.Dosign() // //客户版本 不再需要 @@ -145,105 +147,105 @@ func Demo(roomid ...int) { //附加功能 自动发送即将过期礼物 go reply.AutoSend_silver_gift() - for exit_sign:=true;exit_sign; { + for exit_sign := true; exit_sign; { - danmulog.L(`T: `,"准备") + danmulog.L(`T: `, "准备") //如果连接中断,则等待 F.KeepConnect() //获取热门榜 - F.Get(`Note`) + F.Get(&c.C).Get(`Note`) - danmulog.L(`I: `,"连接到房间", c.Roomid) + danmulog.L(`I: `, "连接到房间", c.C.Roomid) Cookie := make(map[string]string) - c.Cookie.Range(func(k,v interface{})(bool){ + c.C.Cookie.Range(func(k, v interface{}) bool { Cookie[k.(string)] = v.(string) return true }) - F.Get(`Liveing`) + F.Get(&c.C).Get(`Liveing`) //检查与切换粉丝牌,只在cookie存在时启用 - F.Get(`CheckSwitch_FansMedal`) + F.Get(&c.C).Get(`CheckSwitch_FansMedal`) //直播状态 - if c.Liveing { - danmulog.L(`I: `,"直播中") + if c.C.Liveing { + danmulog.L(`I: `, "直播中") } else { - danmulog.L(`I: `,"未直播") + danmulog.L(`I: `, "未直播") } //对每个弹幕服务器尝试 - F.Get(`WSURL`) - for i:=0;i