- name: Check out code
uses: actions/checkout@v3
-
+
+ - name: golangci-lint
+ uses: golangci/golangci-lint-action@v3
+ with:
+ args: --timeout 3m --verbose
+
+ - name: Test
+ run: |
+ sudo apt-get update
+ sudo apt-get install libgtk-3-dev libcairo2-dev libglib2.0-dev
+ go get .
+ CGO_ENABLED=0 go test -v --cover -coverprofile=coverage ./...
+
+ - name: Codecov
+ uses: codecov/codecov-action@v3
+ with:
+ token: ${{secrets.CODECOV_TOKEN}}
+ file: coverage
+
- name: Build
run: |
sudo apt-get update
- name: Check out code
uses: actions/checkout@v3
+ - name: golangci-lint
+ uses: golangci/golangci-lint-action@v3
+ with:
+ args: --timeout 3m --verbose
+
+ - name: Test
+ run: |
+ set CGO_ENABLED=0
+ go get .
+ go test -v --cover -coverprofile=coverage ./...
+
+ - name: Codecov
+ uses: codecov/codecov-action@v3
+ with:
+ token: ${{secrets.CODECOV_TOKEN}}
+ file: coverage
+
- name: Build
run: |
cd demo
branches:
- '**'
paths:
+ - '**.yml'
- '**.go'
- '**.mod'
- '**.sum'
- name: Check out code
uses: actions/checkout@v3
-
- - name: Build
+
+ - name: golangci-lint
+ uses: golangci/golangci-lint-action@v3
+ with:
+ args: --timeout 3m --verbose
+
+ - name: Test
run: |
sudo apt-get update
sudo apt-get install libgtk-3-dev libcairo2-dev libglib2.0-dev
+ go get .
+ CGO_ENABLED=0 go test -v --cover -coverprofile=coverage ./...
+
+ - name: Codecov
+ uses: codecov/codecov-action@v3
+ with:
+ token: ${{secrets.CODECOV_TOKEN}}
+ file: coverage
+
+ - name: Build
+ run: |
cd demo
+ sudo apt-get update
+ sudo apt-get install libgtk-3-dev libcairo2-dev libglib2.0-dev
go get .
CGO_ENABLED=0 go build -v -buildmode=exe -o demo.run main.go
- name: Check out code
uses: actions/checkout@v3
-
+
+ - name: golangci-lint
+ uses: golangci/golangci-lint-action@v3
+ with:
+ args: --timeout 3m --verbose
+
+ - name: Test
+ run: |
+ set CGO_ENABLED=0
+ go get .
+ go test -v --cover -coverprofile=coverage ./...
+
+ - name: Codecov
+ uses: codecov/codecov-action@v3
+ with:
+ token: ${{secrets.CODECOV_TOKEN}}
+ file: coverage
+
- name: Build
run: |
cd demo
demo/main.exe
*.m4s
*.m3u8
-*.flv
demo/build.bat
demo/build.sh
+Reply/0.flv.log
+demo/coverage.txt
+coverage.txt
return nil
}
-func (t *Common) Init() Common {
+func (t *Common) Init() *Common {
t.PID = os.Getpid()
t.StartT = time.Now()
t.Roomid = *roomIdP
if e := t.loadConf(*ckv); e != nil {
- panic(e)
+ if os.IsNotExist(e) {
+ fmt.Println("未能加载配置文件")
+ } else {
+ panic(e)
+ }
}
go func() {
t.Log = t.Log.Level(logmap)
}
- return *t
+ return t
}
func (t *Common) loadConf(customConf string) error {
var data map[string]interface{}
// 64k
- if bb, e := file.New("config/config_K_v.json", 0, true).ReadAll(100, 1<<16); e != nil {
+ f := file.New("config/config_K_v.json", 0, true)
+ if !f.IsExist() {
+ return os.ErrNotExist
+ }
+ if bb, e := f.ReadAll(100, 1<<16); e != nil {
if !errors.Is(e, io.EOF) {
return e
} else {
- json.Unmarshal(bb, &data)
+ _ = json.Unmarshal(bb, &data)
}
}
return fmt.Errorf("无法获取自定义配置文件 %d", req.Response.StatusCode)
} else {
var tmp map[string]interface{}
- json.Unmarshal(req.Respon, &tmp)
+ _ = json.Unmarshal(req.Respon, &tmp)
for k, v := range tmp {
data[k] = v
}
if bb, err := file.New(customConf, 0, true).ReadAll(100, 1<<16); err != nil {
if errors.Is(err, io.EOF) {
var tmp map[string]interface{}
- json.Unmarshal(bb, &tmp)
+ _ = json.Unmarshal(bb, &tmp)
for k, v := range tmp {
data[k] = v
}
t.Message = e.Error()
data, _ = json.Marshal(t)
}
- w.Write(data)
+ _, _ = w.Write(data)
}
}
} else {
f := file.New(`cookie.txt`, 0, true)
- f.Delete()
- f.Write(append([]byte("nol"), source...), true)
+ _ = f.Delete()
+ _, _ = f.Write(append([]byte("nol"), source...), true)
return
}
}
return
} else {
f := file.New(`cookie.txt`, 0, true)
- f.Delete()
- f.Write(append([]byte("pem"), source...), true)
+ _ = f.Delete()
+ _, _ = f.Write(append([]byte("pem"), source...), true)
}
}
}
{ //生成二维码
- qr.WriteFile(img_url, qr.Medium, 256, `qr.png`)
- if !p.Checkfile().IsExist(`qr.png`) {
+ if e := qr.WriteFile(img_url, qr.Medium, 256, `qr.png`); e != nil || !p.Checkfile().IsExist(`qr.png`) {
apilog.L(`E: `, `qr error`)
return
}
//启动web
if scanPath, ok := c.K_v.LoadV("扫码登录路径").(string); ok && scanPath != "" {
c.SerF.Store(scanPath, func(w http.ResponseWriter, _ *http.Request) {
- file.New("qr.png", 0, true).CopyToIoWriter(w, humanize.MByte, true)
+ _ = file.New("qr.png", 0, true).CopyToIoWriter(w, humanize.MByte, true)
})
if c.K_v.LoadV(`扫码登录自动打开标签页`).(bool) {
- open.Run(`http://127.0.0.1:` + c.Stream_url.Port() + scanPath)
+ _ = open.Run(`http://127.0.0.1:` + c.Stream_url.Port() + scanPath)
}
apilog.L(`W: `, `或打开链接扫码登录:`+c.Stream_url.String()+scanPath)
}
case []interface{}:
default:
if data, err := json.Marshal(res.Data); err == nil {
- json.Unmarshal(data, &item)
+ _ = json.Unmarshal(data, &item)
}
}
}
//cookie
- save_cookie(req.Response.Cookies())
+ _ = save_cookie(req.Response.Cookies())
var has bool
for k := range reqf.Cookies_List_2_Map(req.Response.Cookies()) {
if k == `LIVE_BUVID` {
return
}
- save_cookie(req.Response.Cookies())
+ _ = save_cookie(req.Response.Cookies())
var res struct {
Code int `json:"code"`
## bilibili 直播弹幕机
[](https://goreportcard.com/report/github.com/qydysky/bili_danmu)
-
+[](https://codecov.io/gh/qydysky/bili_danmu)
### 当前支持显示/功能
Coder: ass.wrap,
},
}
- f.Write([]byte(ass.header), true)
+ _, _ = f.Write([]byte(ass.header), true)
ass.startT = st
<-contextC.Done()
var streamO = new(sync.Map)
// 获取实例的Common
-func StreamOCommon(roomid int) (array []c.Common) {
+func StreamOCommon(roomid int) (array []*c.Common) {
if roomid != -1 { //返回特定房间
if v, ok := streamO.Load(roomid); ok {
- return []c.Common{v.(*M4SStream).Common()}
+ return []*c.Common{v.(*M4SStream).Common()}
}
} else { //返回所有
streamO.Range(func(_, v interface{}) bool {
var tmp = new(M4SStream)
- if e := tmp.LoadConfig(*c.C.Copy()); e != nil {
+ if e := tmp.LoadConfig(c.C.Copy()); e != nil {
flog.L(`E: `, e)
return
}
}
func init() { //初始化反射型弹幕机
- bb, err := file.New("config/config_auto_reply.json", 0, true).ReadAll(100, 1<<16)
+ f := file.New("config/config_auto_reply.json", 0, true)
+ if !f.IsExist() {
+ return
+ }
+ bb, err := f.ReadAll(100, 1<<16)
if !errors.Is(err, io.EOF) {
return
}
var buf map[string]interface{}
- json.Unmarshal(bb, &buf)
+ _ = json.Unmarshal(bb, &buf)
for k, v := range buf {
if k == v {
continue
t.once.Do(func() {
if path, ok := c.C.K_v.LoadV(`save_to_json`).(string); ok && path != `` {
f := file.New(path, 0, false)
- f.Delete()
- f.Write([]byte("["), true)
+ _ = f.Delete()
+ _, _ = f.Write([]byte("["), true)
f.Close()
t.msg = msgq.NewType[[]byte]()
t.msg.Pull_tag(map[string]func([]byte) (disable bool){
`data`: func(b []byte) (disable bool) {
f := file.New(path, -1, false)
- f.Write(b, true)
- f.Write([]byte(","), true)
+ _, _ = f.Write(b, true)
+ _, _ = f.Write([]byte(","), true)
f.Close()
return false
},
`stop`: func(_ []byte) (disable bool) {
f := file.New(path, -1, false)
- f.Seed(-1, 2)
- f.Write([]byte("]"), true)
+ _ = f.Seed(-1, 2)
+ _, _ = f.Write([]byte("]"), true)
f.Close()
return true
},
flog := flog.Base_add(`进房弹幕`)
//检查与切换粉丝牌,只在cookie存在时启用
- F.Get(&c.C).Get(`CheckSwitch_FansMedal`)
+ F.Get(c.C).Get(`CheckSwitch_FansMedal`)
if v, _ := c.C.K_v.LoadV(`进房弹幕_有粉丝牌时才发`).(bool); v && c.C.Wearing_FansMedal == 0 {
flog.L(`T: `, `无粉丝牌`)
}
if c.C.UpUid == 0 {
- F.Get(&c.C).Get(`UpUid`)
+ F.Get(c.C).Get(`UpUid`)
}
for _, v := range F.Gift_list() {
} else if strings.HasSuffix(p, ".html") {
w.Header().Set("content-type", "text/html")
}
- f.CopyToIoWriter(w, humanize.MByte, true)
+ _ = f.CopyToIoWriter(w, humanize.MByte, true)
})
// 直播流文件列表api
} else if strings.HasSuffix(p, ".html") {
w.Header().Set("content-type", "text/html")
}
- f.CopyToIoWriter(w, humanize.MByte, true)
+ _ = f.CopyToIoWriter(w, humanize.MByte, true)
})
// 流地址
// 屏蔽不需要的消息
func init() {
{ //加载不需要的消息
- bb, err := file.New("config/config_disable_msg.json", 0, true).ReadAll(100, 1<<16)
+ f := file.New("config/config_disable_msg.json", 0, true)
+ if !f.IsExist() {
+ return
+ }
+ bb, err := f.ReadAll(100, 1<<16)
if !errors.Is(err, io.EOF) {
return
}
var buf map[string]interface{}
- json.Unmarshal(bb, &buf)
+ _ = json.Unmarshal(bb, &buf)
for k, v := range buf {
if able, ok := v.(bool); ok { //设置为true时,使用默认显示
if able {
{ //额外 ass 私信
Assf(fmt.Sprintln(sh...))
c.C.Danmu_Main_mq.Push_tag(`guard_update`, nil) //使用连续付费的新舰长无法区分,刷新舰长数
- if uid != 0 {
+ if msg := c.C.K_v.LoadV(`上舰私信`).(string); uid != 0 && msg != "" {
c.C.Danmu_Main_mq.Push_tag(`pm`, send.Pm_item{
Uid: uid,
- Msg: c.C.K_v.LoadV(`上舰私信`).(string),
+ Msg: msg,
}) //上舰私信
}
- if c.C.K_v.LoadV(`额外私信对象`).(float64) != 0 {
+ if msg, uid := c.C.K_v.LoadV(`上舰私信(额外)`).(string), c.C.K_v.LoadV(`额外私信对象`).(float64); uid != 0 && msg != "" {
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),
+ Uid: int(uid),
+ Msg: msg,
}) //上舰私信-对额外
}
}
return
}
var data ws_msg.WATCHED_CHANGE
- json.Unmarshal([]byte(s), &data)
+ _ = json.Unmarshal([]byte(s), &data)
// fmt.Printf("\t观看人数:%d\n", watched)
if data.Data.Num == c.C.Watched {
return
{ //附加功能 弹幕机 封禁 弹幕合并
//对指定弹幕重新录制
- danmuReLiveTriger.Init(&c.C)
+ danmuReLiveTriger.Init(c.C)
danmuReLiveTriger.Check(item.uid, item.msg)
go Danmujif(item.msg)
// if Autobanf(item.msg) {
})
}
if i, e := strconv.Atoi(item.uid); e == nil {
- c.C.Danmu_Main_mq.Push_tag(`pm`, send.Pm_item{
- Uid: i,
- Msg: c.C.K_v.LoadV(`弹幕私信`).(string),
- }) //上舰私信
+ if msg := c.C.K_v.LoadV(`弹幕私信`).(string); msg != "" {
+ c.C.Danmu_Main_mq.Push_tag(`pm`, send.Pm_item{
+ Uid: i,
+ Msg: msg,
+ }) //上舰私信
+ }
}
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),
- }) //上舰私信-对额外
+ if msg, uid := c.C.K_v.LoadV(`上舰私信(额外)`).(string), c.C.K_v.LoadV(`额外私信对象`).(float64); uid != 0 && msg != "" {
+ c.C.Danmu_Main_mq.Push_tag(`pm`, send.Pm_item{
+ Uid: int(uid),
+ Msg: msg,
+ }) //上舰私信-对额外
+ }
}
}
}
front_buf = []byte{}
}
if bufl := keyframe.Size(); confirm_num != bufl {
- keyframe.RemoveBack(bufl - confirm_num)
+ _ = keyframe.RemoveBack(bufl - confirm_num)
}
}()
}
if keyframe_num >= 0 {
- keyframe.Append(buf[tag_offset : tag_offset+tag_size_check+previou_tag_size])
+ _ = keyframe.Append(buf[tag_offset : tag_offset+tag_size_check+previou_tag_size])
}
} else if buf[tag_offset] == audio_tag {
if keyframe_num >= 0 {
- keyframe.Append(buf[tag_offset : tag_offset+tag_size_check+previou_tag_size])
+ _ = keyframe.Append(buf[tag_offset : tag_offset+tag_size_check+previou_tag_size])
}
}
)
func Test_FLVdeal(t *testing.T) {
- flog := file.New("E:\\test\\0.flv.log", 0, false)
- flog.Delete()
+ flog := file.New("0.flv.log", 0, false)
+ _ = flog.Delete()
defer flog.Close()
- f := file.New("E:\\test\\0.flv", 0, false)
+ f := file.New("test/0.flv", 0, false)
defer f.Close()
if f.IsDir() || !f.IsExist() {
t.Log("reach end")
break
}
- buff.Append(buf[:n])
+ _ = buff.Append(buf[:n])
if s := buff.Size(); max < s {
max = s
}
if e != nil {
t.Fatal(e)
}
- flog.Write([]byte(fmt.Sprintf("%d %d %d %d\n", c, len(front_buf), keyframe.Size(), last_available_offset)), true)
+ _, _ = flog.Write([]byte(fmt.Sprintf("%d %d %d %d\n", c, len(front_buf), keyframe.Size(), last_available_offset)), true)
t.Log(c, len(front_buf), keyframe.Size())
- buff.RemoveFront(last_available_offset)
+ _ = buff.RemoveFront(last_available_offset)
}
t.Log("max", humanize.Bytes(uint64(max)))
}
//deal frame
if keyframeMoof {
if v, e := t.buf.HadModified(bufModified); e == nil && v && !t.buf.IsEmpty() {
- keyframe.Append(t.buf.GetPureBuf())
+ _ = keyframe.Append(t.buf.GetPureBuf())
cu = m[0].i
t.buf.Reset()
}
cu = m[6].e
}
if haveKeyframe {
- t.buf.Append(buf[m[0].i:m[6].e])
+ _ = t.buf.Append(buf[m[0].i:m[6].e])
}
return false
},
//deal frame
if keyframeMoof {
if v, e := t.buf.HadModified(bufModified); e == nil && v && !t.buf.IsEmpty() {
- keyframe.Append(t.buf.GetPureBuf())
+ _ = keyframe.Append(t.buf.GetPureBuf())
cu = m[0].i
t.buf.Reset()
}
cu = m[10].e
}
if haveKeyframe {
- t.buf.Append(buf[m[0].i:m[10].e])
+ _ = t.buf.Append(buf[m[0].i:m[10].e])
}
return false
}})
)
func Test_deal(t *testing.T) {
- flog := file.New("E:\\test\\0.flv.log", 0, false)
- flog.Delete()
+ flog := file.New("0.mp4.log", 0, false)
+ _ = flog.Delete()
defer flog.Close()
- f := file.New("E:\\test\\0.mp4", 0, false)
+ f := file.New("test/0.mp4", 0, false)
defer f.Close()
if f.IsDir() || !f.IsExist() {
t.Log("reach end")
break
}
- buff.Append(buf[:n])
+ _ = buff.Append(buf[:n])
if s := buff.Size(); max < s {
max = s
}
t.Log("front_buf")
break
}
- flog.Write([]byte(fmt.Sprintf("%d %d\n", c, len(front_buf))), true)
+ _, _ = flog.Write([]byte(fmt.Sprintf("%d %d\n", c, len(front_buf))), true)
t.Log(c, len(front_buf))
- buff.RemoveFront(last_available_offset)
+ _ = buff.RemoveFront(last_available_offset)
}
t.Log("max", humanize.Bytes(uint64(max)))
}
boot_buf_locker funcCtrl.BlockFunc
last_m4s *m4s_link_item //最后一个切片
m4s_pool *pool.Buf[m4s_link_item] //切片pool
- common c.Common //通用配置副本
+ common *c.Common //通用配置副本
Current_save_path string //明确的直播流保存目录
// 事件周期 start: 开始实例 startRec:开始录制 load:接收到视频头 cut:切 stopRec:结束录制 stop:结束实例
msg *msgq.MsgType[*M4SStream] //实例的各种事件回调
t.m4s_pool.Put(ms...)
}
-func (t *M4SStream) Common() c.Common {
+func (t *M4SStream) Common() *c.Common {
return t.common
}
-func (t *M4SStream) LoadConfig(common c.Common) (e error) {
+func (t *M4SStream) LoadConfig(common *c.Common) (e error) {
t.common = common
t.log = common.Log.Base(`直播流保存`)
func (t *M4SStream) fetchCheckStream() bool {
// 获取流地址
t.common.Live_want_qn = t.config.want_qn
- if F.Get(&t.common).Get(`Live`); len(t.common.Live) == 0 {
+ if F.Get(t.common).Get(`Live`); len(t.common.Live) == 0 {
return false
}
t.log.L(`I: `, "保存到", rel+`/0.`+t.stream_type)
f := file.New(t.config.save_path+"tmp.create", 0, true)
f.Create()
- f.Delete()
+ _ = f.Delete()
} else {
t.log.L(`W: `, err)
}
defer ticker.Stop()
for {
n, e := rc.Read(buf)
- buff.Append(buf[:n])
+ _ = buff.Append(buf[:n])
if e != nil {
t.Stream_msg.PushLock_tag(`close`, nil)
break
}
if last_available_offset > 1 {
// fmt.Println("write Sync")
- buff.RemoveFront(last_available_offset - 1)
+ _ = buff.RemoveFront(last_available_offset - 1)
}
}
}
t.log.L(`I: `, `flv下载开始`)
- r.Reqf(reqf.Rval{
+ _ = r.Reqf(reqf.Rval{
Url: surl.String(),
SaveToPipeWriter: rw,
NoResponse: true,
link.status = 3 // 设置切片状态为下载失败
} else {
link.data.Reset()
- link.data.Append(r.Respon)
+ _ = link.data.Append(r.Respon)
link.status = 2 // 设置切片状态为下载完成
}
}(v)
continue
}
- buf.Append(download_seq[k].data.GetPureBuf())
+ _ = buf.Append(download_seq[k].data.GetPureBuf())
t.putM4s(download_seq[k])
download_seq = append(download_seq[:k], download_seq[k+1:]...)
k -= 1
t.Stream_msg.PushLock_tag(`data`, t.boot_buf)
}
- buf.RemoveFront(last_available_offset)
+ _ = buf.RemoveFront(last_available_offset)
}
// 停止录制
}
// 是否在直播
- F.Get(&t.common).Get(`Liveing`)
+ F.Get(t.common).Get(`Liveing`)
if !t.common.Liveing {
t.log.L(`W: `, `未直播`)
return false
// 主循环
for t.Status.Islive() {
// 是否在直播
- F.Get(&t.common).Get(`Liveing`)
+ F.Get(t.common).Get(`Liveing`)
if !t.common.Liveing {
t.log.L(`W: `, `未直播`)
break
func (t *M4SStream) PusherToFile(contextC context.Context, filepath string, startFunc func(*M4SStream) error, stopFunc func(*M4SStream) error) error {
f := file.New(filepath, 0, false)
defer f.Close()
- f.Delete()
+ _ = f.Delete()
if e := startFunc(t); e != nil {
return e
}
- f.Write(t.getFirstBuf(), true)
+ _, _ = f.Write(t.getFirstBuf(), true)
t.Stream_msg.Pull_tag(map[string]func([]byte) bool{
`data`: func(b []byte) bool {
select {
if len(b) == 0 {
return true
}
- f.Write(b, true)
+ _, _ = f.Write(b, true)
return false
},
`close`: func(_ []byte) bool {
}
}
- bb, err := file.New("config/config_tts.json", 0, true).ReadAll(100, 1<<16)
+ f := file.New("config/config_tts.json", 0, true)
+ if !f.IsExist() {
+ return
+ }
+ bb, err := f.ReadAll(100, 1<<16)
if !errors.Is(err, io.EOF) {
return
}
var buf map[string]interface{}
- json.Unmarshal(bb, &buf)
+ _ = json.Unmarshal(bb, &buf)
if onoff, ok := buf[`onoff`]; ok {
for k, v := range onoff.(map[string]interface{}) {
tts_setting_string[k] = v.(string)
}
}
if len(buf) != 0 {
- file.New(sys.Sys().Cdir()+`/tts.mp3`, 0, true).Write(buf, true)
+ _, _ = file.New(sys.Sys().Cdir()+`/tts.mp3`, 0, true).Write(buf, true)
play()
}
xfwsClient.Close()
// 初始化表情代码
func init() {
- bb, err := file.New("config/config_danmu_official.json", 0, true).ReadAll(1000, 1<<16)
+ f := file.New("config/config_danmu_official.json", 0, true)
+ if !f.IsExist() {
+ return
+ }
+ bb, err := f.ReadAll(1000, 1<<16)
if !errors.Is(err, io.EOF) {
return
}
var buf map[string]interface{}
- json.Unmarshal(bb, &buf)
+ _ = json.Unmarshal(bb, &buf)
for k, v := range buf {
if k == v {
continue
//如果连接中断,则等待
F.KeepConnect()
//获取cookie
- F.Get(&c.C).Get(`Cookie`)
+ F.Get(c.C).Get(`Cookie`)
//获取LIVE_BUVID
- F.Get(&c.C).Get(`LIVE_BUVID`)
+ F.Get(c.C).Get(`LIVE_BUVID`)
// 房间初始化
if c.C.Roomid == 0 {
//使用带tag的消息队列在功能间传递消息
c.C.Danmu_Main_mq.Pull_tag(msgq.FuncMap{
`flash_room`: func(_ any) bool { //房间重进
- F.Get(&c.C).Get(`WSURL`)
+ F.Get(c.C).Get(`WSURL`)
select {
case flash_room_chan <- struct{}{}:
default:
},
`pm`: func(data any) bool { //私信
if tmp, ok := data.(send.Pm_item); ok {
- send.Send_pm(tmp.Uid, tmp.Msg)
+ if e := send.Send_pm(tmp.Uid, tmp.Msg); e != nil {
+ danmulog.Base_add(`私信`).L(`E: `, e)
+ }
}
return false
},
//捕获ctrl+c退出
signal.Notify(interrupt, os.Interrupt)
//获取uid
- F.Get(&c.C).Get(`Uid`)
+ F.Get(c.C).Get(`Uid`)
//兑换硬币
- F.Get(&c.C).Get(`Silver_2_coin`)
+ F.Get(c.C).Get(`Silver_2_coin`)
//每日签到
F.Dosign()
// //客户版本 不再需要
//如果连接中断,则等待
F.KeepConnect()
//获取热门榜
- F.Get(&c.C).Get(`Note`)
+ F.Get(c.C).Get(`Note`)
danmulog.L(`I: `, "连接到房间", c.C.Roomid)
return true
})
- F.Get(&c.C).Get(`Liveing`)
+ F.Get(c.C).Get(`Liveing`)
//检查与切换粉丝牌,只在cookie存在时启用
- F.Get(&c.C).Get(`CheckSwitch_FansMedal`)
+ F.Get(c.C).Get(`CheckSwitch_FansMedal`)
//直播状态
if c.C.Liveing {
}
//对每个弹幕服务器尝试
- F.Get(&c.C).Get(`WSURL`)
+ F.Get(c.C).Get(`WSURL`)
for i := 0; i < len(c.C.WSURL); i += 1 {
v := c.C.WSURL[i]
//ws启动
}()
//订阅消息,以便刷新舰长数
- F.Get(&c.C).Get(`GuardNum`)
+ F.Get(c.C).Get(`GuardNum`)
// 在线人数
- F.Get(&c.C).Get(`getOnlineGoldRank`)
+ F.Get(c.C).Get(`getOnlineGoldRank`)
//当前ws的消息队列
c.C.Danmu_Main_mq.Pull_tag(msgq.FuncMap{
`exit_cu_room`: func(_ any) bool { //退出
return true
},
`guard_update`: func(_ any) bool { //舰长更新
- go F.Get(&c.C).Get(`GuardNum`)
+ go F.Get(c.C).Get(`GuardNum`)
return false
},
`flash_room`: func(_ any) bool { //重进房时退出当前房间
return false
}
// 在线人数
- F.Get(&c.C).Get(`getOnlineGoldRank`)
+ F.Get(c.C).Get(`getOnlineGoldRank`)
return false
},
`new day`: func(_ any) bool { //日期更换
// //获取用户版本 不再需要
// go F.Get(`VERSION`)
//每日兑换硬币
- go F.Get(&c.C).Silver_2_coin()
+ go F.Get(c.C).Silver_2_coin()
//附加功能 每日发送弹幕
go reply.Entry_danmu()
//附加功能 保持牌子点亮
ws_c.Close()
danmulog.L(`I: `, "停止,等待服务器断开连接")
//刷新WSURL
- F.Get(&c.C).Get(`WSURL`)
+ F.Get(c.C).Get(`WSURL`)
i = 0
case <-change_room_chan:
ws_c.Close()
//登陆
if strings.Contains(inputs, ` login`) {
//获取cookie
- F.Get(&c.C).Get(`Cookie`)
+ F.Get(c.C).Get(`Cookie`)
continue
}
//搜索主播
fmt.Println(`Web服务地址:`, c.C.Stream_url.String())
var array = reply.StreamOCommon(-1)
fmt.Println(`正在录制的房间:`)
- for _, v := range array {
- fmt.Println("\t" + v.Uname + "(" + strconv.Itoa(v.Roomid) + ") " + v.Title)
+ for i := 0; i < len(array); i++ {
+ fmt.Println("\t" + array[i].Uname + "(" + strconv.Itoa(array[i].Roomid) + ") " + array[i].Title)
}
fmt.Print("输入` rec` 来启停当前房间录制")