]> 127.0.0.1 Git - bili_danmu/.git/commitdiff
Gtk支持头像
authorqydysky <qydysky@foxmail.com>
Wed, 21 Oct 2020 00:39:52 +0000 (08:39 +0800)
committerqydysky <qydysky@foxmail.com>
Wed, 21 Oct 2020 00:39:52 +0000 (08:39 +0800)
18 files changed:
.gitignore
F/api.go
README.md
Reply/F.go
Reply/Reply.go
Reply/gtk.go
_Screenshot/Screenshot_20201021_082757.png [new file with mode: 0644]
_msg_sample/DANMU_MSG.json
demo/face/0buyguide [new file with mode: 0644]
demo/face/0default [new file with mode: 0644]
demo/face/0gift [new file with mode: 0644]
demo/face/0jiezou [new file with mode: 0644]
demo/face/0level1 [new file with mode: 0644]
demo/face/0level2 [new file with mode: 0644]
demo/face/0level3 [new file with mode: 0644]
demo/face/0room [new file with mode: 0644]
demo/face/0superchat [new file with mode: 0644]
demo/ui/1.glade

index 0f6a3439856d15a7149b7da59f79d051c1ef1d54..56f4cb522504b01e897ed35c0c435c6b3758b2d7 100644 (file)
@@ -12,3 +12,4 @@ demo/*.ass
 demo/*.mkv
 demo/qtbox
 demo/main
+demo/face/*
index c9aababe09f5049cf6bd172b73518b3d490062ac..bb6d101a5f4e177a61bf53f8775c7068cd4d4eb4 100644 (file)
--- a/F/api.go
+++ b/F/api.go
@@ -303,4 +303,37 @@ func (i *api) Get_host_Token() (o *api) {
        }
 
        return
+}
+
+var get_face_src_limit = p.Limit(1, 1000, 2000)
+
+func Get_face_src(uid string) (string) {
+       if uid == "" {return ""}
+       //等待令牌时阻塞,超时返回true
+       if get_face_src_limit.TO() {return ""}
+       apilog.Base(-1, "获取face")
+       defer apilog.Base(0)
+
+       req := p.Req()
+       if err := req.Reqf(p.Rval{
+               Url:"https://api.live.bilibili.com/xlive/web-room/v1/index/getDanmuMedalAnchorInfo?ruid=" + uid,
+               Referer:"https://live.bilibili.com/" + strconv.Itoa(c.Roomid),
+               Timeout:10,
+               Retry:2,
+       });err != nil {
+               apilog.E(err)
+               return ""
+       }
+       res := string(req.Respon)
+       if msg := p.Json().GetValFromS(res, "message");msg == nil || msg != "0" {
+               apilog.E("message", msg)
+               return ""
+       }
+
+       rface := p.Json().GetValFromS(res, "data.rface")
+       if rface == nil {
+               apilog.E("data.rface", rface)
+               return ""
+       }
+       return rface.(string) + `@58w_58h`
 }
\ No newline at end of file
index 31d1c648dd96e0784eb9683a7f44284a0b8459ba..c680a7b1f2cf9f2781214c9ca65401ea3da3f0d8 100644 (file)
--- a/README.md
+++ b/README.md
@@ -56,7 +56,7 @@ var Msg_map = map[string]func(replyF, string) {
 以下内容可能过时,点击查看[当前支持功能](https://github.com/qydysky/bili_danmu/blob/master/Reply/F.go#L16)
 ```
 其他功能
-自动化功能、挑选有价值的弹幕,可在demo/config.json覆盖默认控制
+自动化功能、挑选有价值的弹幕,可在demo/config_F.json覆盖默认控制
 //功能开关
 var AllF = map[string]bool{
        "Saveflv":true,//保存直播流(仅高清)
@@ -81,6 +81,14 @@ var AllF = map[string]bool{
        "Shortdanmu":true,//上下文相同文字缩减
 }
 ```
+以下内容可能过时,其他小功能
+```
+弹幕重连
+直播流开播自动下载
+直播流下载重连
+...
+```
+
 
 ### demo 
 - 已配置了[go环境](https://golang.google.cn/dl/)
@@ -154,6 +162,12 @@ ctrl+c退出,会同时追加记录到文件danmu.log中(文件记录完整
 ![](_Screenshot/Screenshot_20200926_173834.png)
 [截图地址](//zdir.ntsdtt.bid/ALL/Admin/Remote/%E5%9B%BE%E7%89%87/Screenshot_20200926_173834.png)
 
+Gtk弹幕窗
+
+![](_Screenshot/Screenshot_20201021_082757.png)
+
+[截图地址](//zdir.ntsdtt.bid/ALL/Admin/Remote/%E5%9B%BE%E7%89%87/Screenshot_20201021_082757.png)
+
 Qt弹幕窗
 ![](_Screenshot/Screenshot_20201002_045627.png)
 [截图地址](//zdir.ntsdtt.bid/ALL/Admin/Remote/%E5%9B%BE%E7%89%87/Screenshot_20201002_045627.png)
index d124221fde31b94fb7a5906e2a577e4969dcadaa..1618aee0702eaa9d8f50f5821f76f09a01f02788 100644 (file)
@@ -283,21 +283,16 @@ func Saveflvf(){
                }
 
                {//重试
-                       retry := 20
-                       for retry > 0 && rr.ResponseCode != 200 {
-                               if e := rr.Reqf(p.Rval{
-                                       Url:c.Live[cuLinkIndex],
-                                       Retry:10,
-                                       SleepTime:5,
-                                       Cookie:Cookie,
-                                       Timeout:-1,
-                                       JustResponseCode:true,
-                               }); e != nil{l.W(e)}
-                               p.Sys().Timeoutf(2)
-                               retry -= 1
-                       }
-                       if retry == 0 {
-                               p.Sys().Timeoutf(5)
+                       if e := rr.Reqf(p.Rval{
+                               Url:c.Live[cuLinkIndex],
+                               Retry:10,
+                               SleepTime:5,
+                               Cookie:Cookie,
+                               Timeout:-1,
+                               JustResponseCode:true,
+                       }); e != nil{l.W(e)}
+
+                       if rr.ResponseCode != 200 {
                                saveflv.wait.Done()
                                saveflv.cancel.Done()
                                cuLinkIndex += 1
index fcfd1fdd3badd975dd4ba60c5bb5f60374847b27..56ba77240c2ac7111c81a7ccdcdf934b9a41475e 100644 (file)
@@ -151,9 +151,9 @@ func (replyF) user_toast_msg(s string){
        fmt.Println(sh...)
        fmt.Print("====\n\n")
 
-       Gui_show("\n====")
-       Gui_show(Itos(sh))
-       Gui_show("====\n")
+       // Gui_show("\n====")
+       Gui_show(Itos(sh), "0buyguide")
+       // Gui_show("====\n")
 
        msglog.Base(1, "礼").Fileonly(true).I(sh...).Fileonly(false)
 }
@@ -198,9 +198,9 @@ func (replyF) special_gift(s string){
        fmt.Println(sh...)
        fmt.Print("====\n\n")
 
-       Gui_show("\n====")
-       Gui_show(Itos(sh))
-       Gui_show("====\n")
+       // Gui_show("\n====")
+       Gui_show(Itos(sh), "0jiezou")
+       // Gui_show("====\n")
 
        msglog.Base(1, "礼").I(sh...)
 
@@ -247,7 +247,7 @@ func (replyF) room_change(s string){
        if area_name != nil {
                sh = append(sh, area_name)
        }
-       Gui_show(Itos(sh))
+       Gui_show(Itos(sh), "0room")
 
        msglog.Base(1, "房").I(sh...)
 }
@@ -257,14 +257,15 @@ func (replyF) welcome_guard(s string){
 
        username := p.Json().GetValFromS(s, "data.username");
        guard_level := p.Json().GetValFromS(s, "data.guard_level");
+       img := "0default"
 
        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, "舰长")
+               case 1:sh = append(sh, "总督");img="0level1"
+               case 2:sh = append(sh, "提督");img="0level2"
+               case 3:sh = append(sh, "舰长");img="0level3"
                default:sh = append(sh, "等级", guard_level)
                }
        }
@@ -274,7 +275,7 @@ func (replyF) welcome_guard(s string){
 
        fmt.Print(">>> ")
        fmt.Println(sh...)
-       Gui_show(Itos(append([]interface{}{">>> "}, sh...)))
+       Gui_show(Itos(append([]interface{}{">>> "}, sh...)), img)
 
        msglog.Base(1, "房").Fileonly(true).I(sh...).Fileonly(false)
 }
@@ -321,9 +322,9 @@ func (replyF) send_gift(s string){
        fmt.Println(sh...)
        fmt.Print("====\n\n")
 
-       Gui_show("\n====")
-       Gui_show(Itos(sh))
-       Gui_show("====\n")
+       // Gui_show("\n====")
+       Gui_show(Itos(sh), "0gift")
+       // Gui_show("====\n")
        
        msglog.Base(1, "礼").Fileonly(true).I(sh...).Fileonly(false)
 }
@@ -337,7 +338,7 @@ func (replyF) room_block_msg(s string) {
                msglog.E("uname", uname)
                return
        } else {
-               Gui_show(Itos([]interface{}{"用户", uname, "已被封禁"}))
+               Gui_show(Itos([]interface{}{"用户", uname, "已被封禁"}), "0room")
                fmt.Println("用户", uname, "已被封禁")
                msglog.Base(1, "封").I("用户", uname, "已被封禁")
        }
@@ -357,11 +358,11 @@ func (replyF) preparing(s string) {
                        Saveflv_wait()
                }
                if p.Sys().Type(roomid) == "float64" {
-                       Gui_show(Itos([]interface{}{"房间", roomid, "下播了"}))
+                       Gui_show(Itos([]interface{}{"房间", roomid, "下播了"}), "0room")
                        msglog.I("房间", int(roomid.(float64)), "下播了")
                        return
                }
-               Gui_show(Itos([]interface{}{"房间", roomid, "下播了"}))
+               Gui_show(Itos([]interface{}{"房间", roomid, "下播了"}), "0room")
                msglog.I("房间", roomid, "下播了")
        }
 }
@@ -380,11 +381,11 @@ func (replyF) live(s string) {
                        go Saveflvf()
                }
                if p.Sys().Type(roomid) == "float64" {
-                       Gui_show(Itos([]interface{}{"房间", roomid, "开播了"}))
+                       Gui_show(Itos([]interface{}{"房间", roomid, "开播了"}), "0room")
                        msglog.I("房间", int(roomid.(float64)), "开播了")
                        return
                }
-               Gui_show(Itos([]interface{}{"房间", roomid, "开播了"}))
+               Gui_show(Itos([]interface{}{"房间", roomid, "开播了"}), "0room")
                msglog.I("房间", roomid, "开播了")
        }
 }
@@ -406,23 +407,23 @@ func (replyF) super_chat_message(s string){
        }
        fmt.Println("\n====")
        fmt.Println(sh...)
-       Gui_show("\n====")
-       Gui_show(Itos(sh))
+       // Gui_show("\n====")
        if message != nil && message.(string) != ""{
                fmt.Println(message)
-               Gui_show(message.(string))
+               // Gui_show(message.(string))
                sh = append(sh, message)
        }
        if message_jpn != nil && message.(string) != message_jpn.(string) && message_jpn.(string) != "" {
                fmt.Println(message_jpn)
-               Gui_show(message_jpn.(string))
+               // Gui_show(message_jpn.(string))
                sh = append(sh, message_jpn)
        }
        fmt.Print("====\n\n")
        
        {//额外
                Assf(fmt.Sprintln(sh...))
-               Gui_show("====\n")
+               // Gui_show("====\n")
+               Gui_show(Itos(sh), "0superchat")
        }
        msglog.Base(1, "礼").Fileonly(true).I(sh...).Fileonly(false)
 }
@@ -495,6 +496,7 @@ func (replyF) danmu(s string) {
                infob := info.([]interface{})
                msg := infob[1].(string)
                auth := infob[2].([]interface{})[1]
+               uid := strconv.Itoa(int(infob[2].([]interface{})[0].(float64)))
 
                msglog.Fileonly(true)
                defer msglog.Fileonly(false)
@@ -512,7 +514,7 @@ func (replyF) danmu(s string) {
                                return
                        }
                }
-               Msg_showdanmu(auth, msg)
+               Msg_showdanmu(auth, msg, uid)
        }
 }
 
@@ -526,7 +528,8 @@ func Msg_senddanmu(msg string){
 
 //弹幕显示
 //由于额外功能有些需要显示,为了统一管理,使用此方法进行处理
-func Msg_showdanmu(auth interface{}, msg string) {
+func Msg_showdanmu(auth interface{}, m ...string) {
+       msg := m[0]
        {//附加功能 更少弹幕
                if Lessdanmuf(msg, 20) > 0.7 {//与前20条弹幕重复的字数占比度>0.7的屏蔽
                        if auth != nil {msglog.I(auth, ":", msg)}
@@ -537,16 +540,26 @@ func Msg_showdanmu(auth interface{}, msg string) {
                        return
                } else {msg = _msg}
                Assf(msg)//ass
-               Gui_show(fmt.Sprint(auth) +`: `+ msg)
+               if auth != nil {
+                       Gui_show(fmt.Sprint(auth) +`: `+ msg, m[1])
+               } else {
+                       Gui_show(msg)
+               }       
        }
        
        fmt.Println(msg)
        if auth != nil {msglog.I(auth, ":", msg)}
 }
 
-func Gui_show(m string){
-       if QtOn {QtDanmuChan <- m}
-       if Gtk_on {Gtk_danmuChan <- m}
+func Gui_show(m ...string){
+       //m[0]:msg m[1]:uid
+       if QtOn {QtDanmuChan <- m[0]}
+       if Gtk_on {
+               if len(m) > 1 {
+                       Gtk_danmuChan_uid <- m[1]
+               } else {Gtk_danmuChan_uid <- ""}
+               Gtk_danmuChan <- m[0]
+       }
 }
 
 func Itos(i []interface{}) string {
index 223ab4e963490fd5319ad80bda83493e687d1264..263d5082d6f65c60f3242730550da93183caa646 100644 (file)
@@ -7,15 +7,21 @@ import (
 
        "github.com/gotk3/gotk3/glib"
        "github.com/gotk3/gotk3/gtk"
+       "github.com/gotk3/gotk3/gdk"
+       p "github.com/qydysky/part"
+       F "github.com/qydysky/bili_danmu/F"
 )
 
 const appId = "com.github.qydysky.bili_danmu.reply"
-var BList = list.New()
+var BTList = list.New()
+var BIList = list.New()
 
 var (
        Gtk_on bool
        Gtk_Tra bool
-       Gtk_danmuChan chan string = make(chan string, 10)
+       Gtk_img_path string = "face"
+       Gtk_danmuChan chan string = make(chan string, 100)
+       Gtk_danmuChan_uid chan string = make(chan string, 100)
 )
 
 func Gtk_danmu() {
@@ -70,49 +76,64 @@ func Gtk_danmu() {
                        }
                }
 
-               var y func()
-               y = func(){
+               var y func(bool)
+               y = func(tra bool){
+                       Gtk_Tra = true
+                       
                        s:=<-Gtk_danmuChan
                        t,_ := gtk.TextViewNew();
+                       BTList.PushBack(t)
+                       t.SetMarginStart(5)
                        t.SetEditable(false)
                        t.SetHExpand(true)
                        t.SetVExpand(false)
                        t.SetWrapMode(gtk.WRAP_WORD_CHAR)
+                       
+                       img,_ :=gtk.ImageNew();
+                       BIList.PushBack(img)
+
                        var handle glib.SignalHandle
                        handle,_ = t.Connect("size-allocate", func(){
+                               Gtk_Tra = false
                                b,e := t.GetBuffer()
                                if e != nil {return}
                                b.SetText(s)
+
+                               img_src := load_face(<-Gtk_danmuChan_uid)
+                               pixbuf,e := gdk.PixbufNewFromFileAtSize(img_src, 40, 40);
+                               if e != nil {return}
+                               img.SetFromPixbuf(pixbuf)
                                t.HandlerDisconnect(handle)
 
-                               if Gtk_Tra {
-                                       tmp := scrolledwindow0.GetVAdjustment()
-                                       tmp.SetValue(tmp.GetUpper())
+                               if tra {
+                                       handle,_ = t.Connect("size-allocate", func(){
+                                               tmp := scrolledwindow0.GetVAdjustment()
+                                               tmp.SetValue(tmp.GetUpper())
+                                               t.HandlerDisconnect(handle)
+                                       })
                                }
-                               if len(Gtk_danmuChan) != 0 {y()}
+                               if len(Gtk_danmuChan) != 0 {y(tra)}
                        })
 
-                       {
-                               tmp := scrolledwindow0.GetVAdjustment()
-                               h := viewport0.GetViewWindow().WindowGetHeight()
-                               Gtk_Tra = tmp.GetUpper() - tmp.GetValue() < float64(h) + 10
-                       }
-
                        tmp,_ := t.Container.Widget.Cast()
-                       loc := int(grid0.Container.GetChildren().Length());
+                       loc := BTList.Len();
                        grid0.InsertRow(loc);
-                       grid0.Attach(tmp, 0, loc, 1, 1)
-                       if Gtk_Tra && loc > 50 {
-                               l,_ := grid0.GetChildAt(0, 0)
-                               l.ToWidget().Destroy()
+                       grid0.Attach(img, 0, loc - 1, 1, 1)
+                       grid0.Attach(tmp, 1, loc - 1, 1, 1)
+                       for tra && BTList.Len() > 50 {
+                               BTList.Remove(BTList.Front()).(*gtk.TextView).Destroy()
+                               BIList.Remove(BIList.Front()).(*gtk.Image).Destroy()
                                grid0.RemoveRow(0)
                        }
                        win.ShowAll()
                }
 
                glib.TimeoutAdd(uint(100), func() bool {
-                       if len(Gtk_danmuChan) != 0 {y()}
-                       
+                       if !Gtk_Tra && len(Gtk_danmuChan) != 0 {
+                               tmp := scrolledwindow0.GetVAdjustment()
+                               h := viewport0.GetViewWindow().WindowGetHeight()
+                               y(tmp.GetUpper() - tmp.GetValue() < float64(h) * 1.3)
+                       }
                        return true
                })
                win.Show()
@@ -142,3 +163,18 @@ func isWindow(obj glib.IObject) (*gtk.Window, error) {
 func onMainWindowDestroy() {
        log.Println("onMainWindowDestroy")
 }
+
+func load_face(uid string) string {
+       defaultuid := "0default"
+       if uid != "" && p.Checkfile().IsExist(Gtk_img_path + `/` + uid) {return Gtk_img_path + `/` + uid}
+       if src := F.Get_face_src(uid);src != "" {
+               req := p.Req()
+               if e := req.Reqf(p.Rval{
+                       Url:src,
+                       SaveToPath:Gtk_img_path + `/` + uid,
+                       Timeout:3,
+               }); e != nil{log.Println(e);return Gtk_img_path + `/` + defaultuid}
+               return Gtk_img_path + `/` + uid
+       }
+       return Gtk_img_path + `/` + defaultuid
+}
\ No newline at end of file
diff --git a/_Screenshot/Screenshot_20201021_082757.png b/_Screenshot/Screenshot_20201021_082757.png
new file mode 100644 (file)
index 0000000..4fffb8d
Binary files /dev/null and b/_Screenshot/Screenshot_20201021_082757.png differ
index 9b80a0651d36198ff9be93221235187acf8baa42..8238da123e64eb427ebfbe41af33de7153f8c300 100644 (file)
-{
-    "cmd": "DANMU_MSG",
-    "info": [
-        [
-            0,
-            1,
-            25,
-            16777215,
-            1601981229550,
-            925883313,
-            0,
-            "7a317c96",
-            0,
-            0,
-            0,
-            ""
-        ],
-        "鬼也是玩家吗",
-        [
-            332143945,
-            "爱吃甜食的叱干巧曼",
-            0,
-            0,
-            0,
-            10000,
-            1,
-            ""
-        ],
-        [
-            7,
-            "猫良",
-            "数字猫",
-            3839755,
-            5805790,
-            "",
-            0,
-            5805790,
-            5805790,
-            5805790,
-            0,
-            1,
-            6009977
-        ],
-        [
-            7,
-            0,
-            9868950,
-            "\u003e50000"
-        ],
-        [
-            "",
-            ""
-        ],
-        0,
-        0,
-        null,
-        {
-            "ts": 1601981229,
-            "ct": "EE03F05F"
-        },
-        0,
-        0,
-        null,
-        null,
-        0
-    ]
-}
\ No newline at end of file
+[
+    {
+        "cmd": "DANMU_MSG",
+        "info": [
+            [
+                0,
+                1,
+                25,
+                16777215,
+                1601981229550,
+                925883313,
+                0,
+                "7a317c96",
+                0,
+                0,
+                0,
+                ""
+            ],
+            "鬼也是玩家吗",
+            [
+                332143945,
+                "爱吃甜食的叱干巧曼",
+                0,
+                0,
+                0,
+                10000,
+                1,
+                ""
+            ],
+            [
+                7,
+                "猫良",
+                "数字猫",
+                3839755,
+                5805790,
+                "",
+                0,
+                5805790,
+                5805790,
+                5805790,
+                0,
+                1,
+                6009977
+            ],
+            [
+                7,
+                0,
+                9868950,
+                "\u003e50000"
+            ],
+            [
+                "",
+                ""
+            ],
+            0,
+            0,
+            null,
+            {
+                "ts": 1601981229,
+                "ct": "EE03F05F"
+            },
+            0,
+            0,
+            null,
+            null,
+            0
+        ]
+    },
+    {
+        "cmd": "DANMU_MSG",
+        "info": [
+            [
+                0,
+                4,
+                25,
+                14893055,
+                1603237288525,
+                1603237302,
+                0,
+                "0d9a2aee",
+                0,
+                0,
+                5,
+                "#1953BAFF,#3353BAFF,#3353BAFF"
+            ],
+            "谢谢VVVVVega_赠送的3个吃瓜~",
+            [
+                2905179,
+                "猫辞の小哥哥",
+                1,
+                0,
+                0,
+                10000,
+                1,
+                "#00D1F1"
+            ],
+            [],
+            [
+                25,
+                0,
+                5805790,
+                "\u003e50000"
+            ],
+            [
+                "title-131-2",
+                "title-131-2"
+            ],
+            0,
+            3,
+            null,
+            {
+                "ts": 1603237288,
+                "ct": "8E0D62CD"
+            },
+            0,
+            0,
+            null,
+            null,
+            0
+        ]
+    },
+    {
+        "cmd": "DANMU_MSG",
+        "info": [
+            [
+                0,
+                4,
+                25,
+                14893055,
+                1603237313448,
+                2130913535,
+                0,
+                "dc5c2dd7",
+                0,
+                0,
+                5,
+                "#1953BAFF,#3353BAFF,#3353BAFF"
+            ],
+            "点歌 drop pop candy",
+            [
+                68283513,
+                "此方伍仁",
+                1,
+                0,
+                0,
+                10000,
+                1,
+                "#00D1F1"
+            ],
+            [
+                25,
+                "猫辞的",
+                "猫辞猫辞猫",
+                1033927,
+                398668,
+                "",
+                0,
+                6809855,
+                398668,
+                6850801,
+                3,
+                1,
+                17794913
+            ],
+            [
+                14,
+                0,
+                6406234,
+                "\u003e50000"
+            ],
+            [
+                "",
+                ""
+            ],
+            0,
+            3,
+            null,
+            {
+                "ts": 1603237313,
+                "ct": "8858B986"
+            },
+            0,
+            0,
+            null,
+            null,
+            0
+        ]
+    },
+    {
+        "cmd": "DANMU_MSG",
+        "info": [
+            [
+                0,
+                1,
+                25,
+                16772431,
+                1603237890865,
+                -847143969,
+                0,
+                "94ccf920",
+                0,
+                0,
+                5,
+                "#1953BAFF,#3353BAFF,#3353BAFF"
+            ],
+            "(`・ω・´)",
+            [
+                4995588,
+                "桜花喵喵_Official",
+                1,
+                0,
+                0,
+                10000,
+                1,
+                "#00D1F1"
+            ],
+            [
+                1,
+                "渣女",
+                "清泉qwq",
+                755732,
+                6406234,
+                "",
+                0,
+                6406234,
+                6406234,
+                6406234,
+                0,
+                1,
+                47355
+            ],
+            [
+                28,
+                0,
+                5805790,
+                "\u003e50000"
+            ],
+            [
+                "title-360-1",
+                "title-360-1"
+            ],
+            0,
+            3,
+            null,
+            {
+                "ts": 1603237890,
+                "ct": "64A75043"
+            },
+            0,
+            0,
+            null,
+            null,
+            0
+        ]
+    },
+    {
+        "cmd": "DANMU_MSG",
+        "info": [
+            [
+                0,
+                1,
+                25,
+                5566168,
+                1603238036517,
+                389215823,
+                0,
+                "276ad711",
+                0,
+                0,
+                0,
+                ""
+            ],
+            "叫 可乐",
+            [
+                407515746,
+                "绿洲骆驼_",
+                0,
+                0,
+                0,
+                10000,
+                1,
+                ""
+            ],
+            [
+                13,
+                "猫辞的",
+                "猫辞猫辞猫",
+                1033927,
+                16746162,
+                "",
+                0,
+                16746162,
+                16746162,
+                16746162,
+                0,
+                1,
+                17794913
+            ],
+            [
+                10,
+                0,
+                9868950,
+                "\u003e50000"
+            ],
+            [
+                "",
+                ""
+            ],
+            0,
+            0,
+            null,
+            {
+                "ts": 1603238036,
+                "ct": "BDCA4AF3"
+            },
+            0,
+            0,
+            null,
+            null,
+            0
+        ]
+    },
+    {
+        "cmd": "DANMU_MSG",
+        "info": [
+            [
+                0,
+                1,
+                25,
+                5566168,
+                1603238308586,
+                -1373134828,
+                0,
+                "6cf1b82b",
+                0,
+                0,
+                0,
+                ""
+            ],
+            "上课(=・ω・=)",
+            [
+                289838259,
+                "菲莉娅Official",
+                0,
+                0,
+                0,
+                10000,
+                1,
+                ""
+            ],
+            [
+                22,
+                "伞妃",
+                "小伞一把Kokasa",
+                26283,
+                1725515,
+                "",
+                0,
+                6809855,
+                1725515,
+                5414290,
+                3,
+                1,
+                1740548
+            ],
+            [
+                24,
+                0,
+                5805790,
+                "\u003e50000"
+            ],
+            [
+                "title-352-1",
+                "title-352-1"
+            ],
+            0,
+            0,
+            null,
+            {
+                "ts": 1603238308,
+                "ct": "71FE2286"
+            },
+            0,
+            0,
+            null,
+            null,
+            0
+        ]
+    },
+    {
+        "cmd": "DANMU_MSG",
+        "info": [
+            [
+                0,
+                4,
+                25,
+                16750592,
+                1603238461862,
+                1073881206,
+                0,
+                "3b60f872",
+                0,
+                0,
+                5,
+                "#1953BAFF,#3353BAFF,#3353BAFF"
+            ],
+            "25牌牌就蓝了",
+            [
+                19277984,
+                "养猫博士",
+                1,
+                1,
+                1,
+                10000,
+                1,
+                "#00D1F1"
+            ],
+            [],
+            [
+                49,
+                0,
+                16746162,
+                8170
+            ],
+            [
+                "title-306-1",
+                "title-306-1"
+            ],
+            0,
+            3,
+            null,
+            {
+                "ts": 1603238461,
+                "ct": "E82EAD"
+            },
+            0,
+            0,
+            null,
+            null,
+            0
+        ]
+    }
+]
\ No newline at end of file
diff --git a/demo/face/0buyguide b/demo/face/0buyguide
new file mode 100644 (file)
index 0000000..fe1ca04
Binary files /dev/null and b/demo/face/0buyguide differ
diff --git a/demo/face/0default b/demo/face/0default
new file mode 100644 (file)
index 0000000..e87555f
Binary files /dev/null and b/demo/face/0default differ
diff --git a/demo/face/0gift b/demo/face/0gift
new file mode 100644 (file)
index 0000000..c759cb5
Binary files /dev/null and b/demo/face/0gift differ
diff --git a/demo/face/0jiezou b/demo/face/0jiezou
new file mode 100644 (file)
index 0000000..83b52c6
Binary files /dev/null and b/demo/face/0jiezou differ
diff --git a/demo/face/0level1 b/demo/face/0level1
new file mode 100644 (file)
index 0000000..582f13a
Binary files /dev/null and b/demo/face/0level1 differ
diff --git a/demo/face/0level2 b/demo/face/0level2
new file mode 100644 (file)
index 0000000..5b4a16c
Binary files /dev/null and b/demo/face/0level2 differ
diff --git a/demo/face/0level3 b/demo/face/0level3
new file mode 100644 (file)
index 0000000..ee3c0b1
Binary files /dev/null and b/demo/face/0level3 differ
diff --git a/demo/face/0room b/demo/face/0room
new file mode 100644 (file)
index 0000000..e46bcd0
Binary files /dev/null and b/demo/face/0room differ
diff --git a/demo/face/0superchat b/demo/face/0superchat
new file mode 100644 (file)
index 0000000..2ed447d
Binary files /dev/null and b/demo/face/0superchat differ
index 7d1041552127fc9d9794608416236b77c22a4bc9..8e681587638c1f68bfa849d246b34f315eb3b444 100644 (file)
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
                 <property name="orientation">vertical</property>
+                <property name="row_spacing">3</property>
+                <property name="column_spacing">2</property>
+                <child>
+                  <placeholder/>
+                </child>
                 <child>
                   <placeholder/>
                 </child>