package bili_danmu
import (
- "fmt"
+ "strconv"
"bytes"
"sync"
"time"
"Danmuji":true,//反射型弹幕机,回应弹幕
"Danmuji_auto":false,//自动型弹幕机,定时输出
"Autoskip":true,//刷屏缩减,相同合并
- "Lessdanmu":false,//弹幕缩减,显示差异大的
+ "Lessdanmu":true,//弹幕缩减,屏蔽与前n条弹幕重复的字数占比度高于阈值的弹幕
"Moredanmu":false,//弹幕增量
+ "Shortdanmu":true,//上下文相同文字缩减
}
func IsOn(s string) bool {
}
autoskip.num -= 1
i, ok := autoskip.buf.LoadAndDelete(s);
- if ok && i.(int) > 1 {fmt.Println(s, "+", i)}
+ if ok && i.(int) > 1 {Msg_showdanmu(nil, strconv.Itoa(i.(int)) + " x " + s)}
}()
return 0
}
type Lessdanmu struct {
Inuse bool
buf []string
-
- avg float32
}
var lessdanmu = Lessdanmu{
Inuse:IsOn("Lessdanmu"),
}
-func Lessdanmuf(s string, bufsize int) bool {
+func Lessdanmuf(s string, bufsize int, drop float32) bool {
if !lessdanmu.Inuse {return false}
- if len(lessdanmu.buf) > bufsize {
- lessdanmu.buf = append(lessdanmu.buf[1:], s)
- } else {
+ if len(lessdanmu.buf) < bufsize {
lessdanmu.buf = append(lessdanmu.buf, s)
+ return false
}
o := cross(s, lessdanmu.buf)
- lessdanmu.avg = (95 * lessdanmu.avg + 5 * o) / 100
- return o < lessdanmu.avg
+ if o == 1 {return true}//完全无用
+ lessdanmu.buf = append(lessdanmu.buf[1:], s)
+
+ return o > drop
}
func cross(a string,buf []string) (float32) {
var s float32
+ var matched bool
for _,v1 := range a {
- var matched bool
for _,v2 := range buf {
for _,v3 := range v2 {
if v3 == v1 {matched = true;break}
if matched {break}
}
if matched {s += 1}
+ matched = false
}
- return s / float32(len(a))
+ return s / float32(len([]rune(a)))
}
/*
原理:留存弹幕,称为buf。将当前若干弹幕在buf中的位置找出,根据位置聚集情况及该位置出现语句的频率,选择发送的弹幕
*/
type Moredanmu struct {}
+
+type Shortdanmu struct {
+ Inuse bool
+ lastdanmu []rune
+}
+
+var shortdanmu = Shortdanmu{
+ Inuse:IsOn("Shortdanmu"),
+}
+
+func Shortdanmuf(s string) string {
+ if !shortdanmu.Inuse {return s}
+ if len(shortdanmu.lastdanmu) == 0 {shortdanmu.lastdanmu = []rune(s);return s}
+
+ var new string
+
+ for k,v := range []rune(s) {
+ if k >= len(shortdanmu.lastdanmu) {
+ new += string([]rune(s)[k:])
+ break
+ }
+ if v != shortdanmu.lastdanmu[k] {
+ switch k {
+ case 0, 1, 2:new = s
+ default:new = "..." + string([]rune(s)[k-1:])
+ }
+ break
+ }
+ }
+ if new == "" {new = "...."}
+ shortdanmu.lastdanmu = []rune(s)
+ return new
+}
"USER_TOAST_MSG":nil,
"WIN_ACTIVITY":nil,
"GUARD_BUY":replayF.guard_buy,//大航海购买
- "WELCOME_GUARD":nil,//replayF.welcome_guard,//大航海进入
+ "WELCOME_GUARD":replayF.welcome_guard,//大航海进入
"DANMU_MSG":replayF.danmu,//弹幕
"ROOM_CHANGE":replayF.room_change,//房间信息分区改变
"ROOM_SILENT_OFF":replayF.roomsilent,//禁言结束
"SUPER_CHAT_MESSAGE":nil,//replayF.super_chat_message,//打赏
"SUPER_CHAT_MESSAGE_JPN":replayF.super_chat_message,//打赏
"PANEL":replayF.panel,//排行榜
- "ENTRY_EFFECT":replayF.entry_effect,//进入特效
+ "ENTRY_EFFECT":nil,//replayF.entry_effect,//进入特效
"ROOM_REAL_TIME_MESSAGE_UPDATE":nil,//replayF.roominfo,//粉丝数
}
var sh = []interface{}{"欢迎"}
+ if guard_level != nil {
+ switch guard_level.(float64) {
+ case 1:sh = append(sh, "总督")
+ case 2:sh = append(sh, "提督")
+ case 3:sh = append(sh, "舰长")
+ default:sh = append(sh, "等级", guard_level)
+ }
+ }
if username != nil {
sh = append(sh, username, "进入直播间")
}
- if guard_level != nil {
- sh = append(sh, "等级", guard_level)
- }
- msglog.Base(1, "房").I(sh...)
+ fmt.Print(">>> ")
+ fmt.Println(sh...)
+
+ msglog.Base(1, "房").Fileonly(true).I(sh...).Fileonly(false)
}
func (replayF) send_gift(s string){
msglog.E("roomid", roomid)
return
} else {
+ if p.Sys().Type(roomid) == "float64" {
+ msglog.I("房间", int(roomid.(float64)), "下播了")
+ return
+ }
msglog.I("房间", roomid, "下播了")
}
}
msglog.E("roomid", roomid)
return
} else {
+ if p.Sys().Type(roomid) == "float64" {
+ msglog.I("房间", int(roomid.(float64)), "开播了")
+ return
+ }
msglog.I("房间", roomid, "开播了")
}
}
msglog.I(auth, ":", msg)
return
}
- if Lessdanmuf(msg, 200) {
- msglog.I(auth, ":", msg)
- return
- }
- fmt.Println(msg)
+ Msg_showdanmu(auth, msg)
msglog.I(auth, ":", msg)
}
}
+
+func Msg_showdanmu(auth interface{}, msg string) {
+ if Lessdanmuf(msg, 20, 0.5) {//与前20条弹幕重复的字数占比度>0.5的屏蔽
+ if auth != nil {msglog.I(auth, ":", msg)}
+ return
+ }
+ fmt.Println(Shortdanmuf(msg))
+}
\ No newline at end of file
"USER_TOAST_MSG":nil,
"WIN_ACTIVITY":nil,
"GUARD_BUY":replayF.guard_buy,//大航海购买
- "WELCOME_GUARD":nil,//replayF.welcome_guard,//大航海进入
+ "WELCOME_GUARD":replayF.welcome_guard,//大航海进入
"DANMU_MSG":replayF.danmu,//弹幕
"ROOM_CHANGE":replayF.room_change,//房间信息分区改变
"ROOM_SILENT_OFF":replayF.roomsilent,//禁言结束
"SUPER_CHAT_MESSAGE":nil,//replayF.super_chat_message,//打赏
"SUPER_CHAT_MESSAGE_JPN":replayF.super_chat_message,//打赏
"PANEL":replayF.panel,//排行榜
- "ENTRY_EFFECT":replayF.entry_effect,//进入特效
+ "ENTRY_EFFECT":nil,//replayF.entry_effect,//进入特效
"ROOM_REAL_TIME_MESSAGE_UPDATE":nil,//replayF.roominfo,//粉丝数
}
其他功能
+自动化功能、挑选有价值的弹幕
//功能开关
var AllF = map[string]bool{
"Autoban":false,//自动封禁(仅提示,未完成)
"Danmuji":true,//反射型弹幕机,回应弹幕
"Danmuji_auto":false,//自动型弹幕机,定时输出
"Autoskip":true,//刷屏缩减,相同合并
- "Lessdanmu":true,//弹幕缩减,显示差异大的
+ "Lessdanmu":true,//弹幕缩减,屏蔽与前n条弹幕重复的字数占比度高于阈值的弹幕
+ "Moredanmu":false,//弹幕增量
+ "Shortdanmu":true,//上下文相同文字缩减
}
-
```
### demo
INFO: 2020/09/16 16:48:11 [bili_danmu.go 测试] [连接 wss://tx-sh-live-comet-01.chat.bilibili.com/sub]
INFO: 2020/09/16 16:48:11 [bili_danmu.go 测试] [已连接到房间 213]
INFO: 2020/09/16 16:48:11 [bili_danmu.go 测试] [开始心跳]
-欢迎舰长 <%初鑫不变%> 进入直播间
-C语言get DAZE! + 10
+>>> 欢迎 舰长 茶摊儿在森林喝碗山海 进入直播间
老鸡捉小鹰
你快扒拉他
你这好像是补刀
====
孤单猫与淋雨猪 投喂 1314 x 辣条 ( 131400 x 金瓜子 )
====
+7 x 原神公测B服冲冲冲
+原神公测B站冲冲冲
+...B服冲冲冲
-ctrl+c退出,日志会同时追加记录到文件danmu.log中(文件记录完整信息)
+ctrl+c退出,日志会同时追加记录到文件danmu.log中(文件记录完整信息,不会减少附加功能作用的弹幕)
```
更多内容详见注释,如有疑问请发issues,欢迎pr
\ No newline at end of file
github.com/qydysky/part v0.0.0-20200915060427-df3e1d541451/go.mod h1:+8N3UgJBVyJj8ar31eZtucwrKpLpay854Y5qq0xk3x0=
github.com/qydysky/part v0.0.0-20200915064846-d3f2213b9508 h1:RQgjB7cwDWinNOVRkstHrYaZUydCwyZFvoiVtZX7rKo=
github.com/qydysky/part v0.0.0-20200915064846-d3f2213b9508/go.mod h1:+8N3UgJBVyJj8ar31eZtucwrKpLpay854Y5qq0xk3x0=
+github.com/qydysky/part v0.0.0-20200917071511-9f829642b501 h1:KYRfCW7+5t3Sj2+j8nn+WWIRhEyyYG/n8N500oEp6yU=
+github.com/qydysky/part v0.0.0-20200917071511-9f829642b501/go.mod h1:+8N3UgJBVyJj8ar31eZtucwrKpLpay854Y5qq0xk3x0=
github.com/shirou/gopsutil v2.20.7+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v2.20.8+incompatible h1:8c7Atn0FAUZJo+f4wYbN0iVpdWniCQk7IYwGtgdh1mY=
github.com/shirou/gopsutil v2.20.8+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200915050820-6d893a6b696e h1:RGS7MuoO4EeRp68J5OWuANAi5oVYtLRl+3LoD5fkMns=
golang.org/x/sys v0.0.0-20200915050820-6d893a6b696e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200917061948-648f2a039071 h1:t0H7WMwCt9t0LnLSYz5zdZ/OiAtROxc5cHb5iHt3Xyw=
+golang.org/x/sys v0.0.0-20200917061948-648f2a039071/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
require (
github.com/gorilla/websocket v1.4.2
github.com/klauspost/compress v1.11.0 // indirect
- github.com/qydysky/part v0.0.0-20200915064846-d3f2213b9508
+ github.com/qydysky/part v0.0.0-20200917071511-9f829642b501
github.com/shirou/gopsutil v2.20.8+incompatible // indirect
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a // indirect
golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect
- golang.org/x/sys v0.0.0-20200915050820-6d893a6b696e // indirect
+ golang.org/x/sys v0.0.0-20200917061948-648f2a039071 // indirect
)
//replace github.com/qydysky/part => ../part
github.com/qydysky/part v0.0.0-20200915060427-df3e1d541451/go.mod h1:+8N3UgJBVyJj8ar31eZtucwrKpLpay854Y5qq0xk3x0=
github.com/qydysky/part v0.0.0-20200915064846-d3f2213b9508 h1:RQgjB7cwDWinNOVRkstHrYaZUydCwyZFvoiVtZX7rKo=
github.com/qydysky/part v0.0.0-20200915064846-d3f2213b9508/go.mod h1:+8N3UgJBVyJj8ar31eZtucwrKpLpay854Y5qq0xk3x0=
+github.com/qydysky/part v0.0.0-20200917071511-9f829642b501 h1:KYRfCW7+5t3Sj2+j8nn+WWIRhEyyYG/n8N500oEp6yU=
+github.com/qydysky/part v0.0.0-20200917071511-9f829642b501/go.mod h1:+8N3UgJBVyJj8ar31eZtucwrKpLpay854Y5qq0xk3x0=
github.com/shirou/gopsutil v2.20.7+incompatible h1:Ymv4OD12d6zm+2yONe39VSmp2XooJe8za7ngOLW/o/w=
github.com/shirou/gopsutil v2.20.7+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v2.20.8+incompatible h1:8c7Atn0FAUZJo+f4wYbN0iVpdWniCQk7IYwGtgdh1mY=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200915050820-6d893a6b696e h1:RGS7MuoO4EeRp68J5OWuANAi5oVYtLRl+3LoD5fkMns=
golang.org/x/sys v0.0.0-20200915050820-6d893a6b696e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200917061948-648f2a039071 h1:t0H7WMwCt9t0LnLSYz5zdZ/OiAtROxc5cHb5iHt3Xyw=
+golang.org/x/sys v0.0.0-20200917061948-648f2a039071/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=