[toc]
F12
打开【开发者工具】,Network - XHR%ai_name%,%greet%%tone/punc%
将发送:某某某,早上好啊~[%guard%]*欢迎%guard_name% %ai_name% 回家~
[%come_time%>%timestamp%-3600*24*30, %come_time%<%timestamp%-3600*24*7, 0]*%ai_name%,太久没来了哦~
[%pk_opposite%]***欢迎%ai_name%串门哦~
谢谢 %ai_name% 的%gift_name%~
[%gift_gold%=0, %gift_silver%<1000, %gift_num% < 10]**
也可以写作:[%coin_type%=0, %gift_coin%<1000, %gift_num% < 10]**
1000以下的银瓜子礼物且数量小于10,则忽略。例如忽略6个小心心,但24个小心心则感谢[%gift_gold%>=80000]*哇噢!感谢 %ai_name% 的%gift_name%!\n老板大气!!!!!!
\n
表示换行,将分作两条弹幕发送(可以配合<h1>
放大字体,仅部分弹幕插件有效)[%uid%=%my_uid%,%origin_gift_name%=吃瓜]**
http://localhost:5520
+ 路径。http://localhost:5520/music/index.html
关闭欢迎
、开启录播
等命令,可远程控制在服务器上的机器人(本地没必要使用远程命令)。background: white; padding:5px; border-radius: 10px;
padding:10px; border-image: url(:/bubbles/bubble1)
border-image: url(C:/Path/To/Image.png)
#danmaku { border-image: url(:/bubbles/bubble1); padding: 10px; } #gift, #guard-buy { background: #FFDAB9; padding: 5px; border-radius: 10px; }
%
包括的英文,则为变量。数据变量例如 %uname%
,与当前的一系列数据相关,例如礼物价值、今日人数等等;招呼变量例如 %greet%
,自动替换为当前时间段对应的招呼语,例如候选项表达式 %ai_name%,%greet%%tone/punc%
,在早上可能是“早上好啊,某某某”,在下午可能是“某某某,下午好~”,在晚上又会是“晚饭吃了吗,某某某~”。欢迎 %ai_name% 光临~
%ai_name%,%greet%%tone/punc%
[]
、()
、,
,不支持中文的 【】
、()
、,
等。>setValue(count, %[%{count}%+1]%)\n数量:%{count}%
>setValue(count, %[%{count}%+1]%)\n数量:%[%{count}%+1]%
[]
开头,则方括号中的内容会识别为条件表达式
,使用 ,
或 &&
来执行“与”逻辑,使用 ;
或 ||
来执行“或”逻辑;“或”的优先级更高。[]
中使用 %val%
作为变量值,例如 [%level%>10]弹幕内容
,则只有当用户等级超过10级时才会被发送弹幕内容
。[[条件]]
或者三方括号 [[[条件]]]
来替换单方括号。[%level%=0]
或 [%level% == 0]
[%medal_level%>=10, %medal_level%<20]
[%uname%=某某某]
或 ["%nickname%"=="某某某"]
[%time_hour% > 17 || %time_hour% <= 6]
[%anchor_room_id%, %level%]
[%total_gold% >= 20000000]
[%come_time% > %timestamp%-3600]
[%come_time%>%timestamp%-3600*24*30 && %come_time%<%timestamp%-3600*24*7]
[[%text% ~ "[\u4e00-\u9fa5]+[\w]{3}[\u4e00-\u9fa5]+"]]>block(%uid%)
*
开头(若有条件表达式 [exp]
,则*
位于表达式后面),星号数量越多,则优先级越高。高优先级候选应当带有条件,当满足条件时,发送该条弹幕,并无视掉所有更低优先级的候选。感谢 %ai_name% 的%gift_name%,么么哒~ [%gift_gold%>=10000]感谢 %ai_name% 的%gift_name%,老板大气! [%gift_gold%>=50000]*(cd15:3)哇塞!感谢 %ai_name% 的%gift_name%!\n老板大气! [%gift_gold%>=150000]**(cd16:1)哇噢!感谢 %ai_name% 的%gift_name%!\n老板大气!!!!!!
冷却通道
,表示不使用默认的送礼冷却。以4为例,改为冷却1秒,相当于强制发送(B站限制,最快1秒)。setValuesIf(exp, [condition], newVal)
、removeValuesIf(exp, [condition])
这两个较为复杂的命令。exp
为正则表达式,将会操作所有key满足该表达式的配置。[condition]
中:_VALUE_
替换为当前遍历到的值(value)_$x_
替换为exp正则捕获的文字,其中x=0
时为键(key),x>0
时为正则的捕获组,等同于自动回复中的 %$x%
_{key}_
替换为读取配置文件,等同于正常情况下的 %{key}%
newVal
中:_[exp]_
替换为计算表达式(不支持外面再嵌套任意内容)removeValuesIf(not_come_(\d+), [_VALUE_>7])
setValuesIf(signin_keep_(\d+), [!_{signin_today__$1_}_], 0)
setValuesIf(guard_days_\d+, [1], _[_VALUE_+1]_)
showValueTable(caption, key, field1, field2, field3...)
caption
是最顶上的标题,支持变量。key
为用来遍历的带有可变值的正则表达式,例如 integral_(\d+)
,将会遍历所有使用setValue
存储的键满足这个表达式的数值。其中必须有带括号的捕获组形如 (\d+)
作为变化的源头,用来影响所有field
的变化;而在各 field
中可以使用 _KEY_
或者 _ID_
来替换为该值。field
允许多个,每个的格式为:标题:键
,标题是表格的标题(第一行),键是用来读取响应设置的。标题及中间的冒号可忽略。用 _KEY_
或 _ID_
来替换为表达式中变化源。单个数字类型的 field
末尾允许用 :<
从小到大、:>
从大到小排序,详见下方示例。key
和field
中,可使用 _counts/
、_heaps/
前缀来指定读取哪一个配置文件,key
默认为_heaps
即用户自定义的配置;field
默认跟随key
的配置。_counts/
文件为安装目录/danmaku_counts/房号.ini
,自动保存每个直播间的数据,不同直播间不共享;_heaps/
为安装目录/heaps.ini
,所有直播间共享一套数据。getData
、postData
、postJson
,最后一个参数可带有一个“回调入口”。其实这是一个事件,添加该回调同名的事件,即可获取到联网返回的数据。%.键1.键2.键3%
这样的格式依次获取JSON对象的值,例如:{ "data": { "room": { "roomname": "房间名字" }, "anchor": { "uname": "名字", } } }
%.data.room.roomname%
,uname获取方式:%.data.anchor.uname%
%.data.list?.1000?%
,当没有list或者list数量不到1000时,会返回空白文本。“?”只影响单个键或者索引,例如若没有data,会原样返回 %.data.list?.1000?%
,相当于报错。>getData(https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom?room_id=%room_id%, RoomInfoCallBack)
RoomInfoCallBack
,动作:>localNotify(舰长数量:%.data.guard_info.count%,\ 粉丝数量:%.data.anchor_info.relation_info.attention%,\ 粉丝团:%.data.anchor_info.medal_info.fansclub%,\ 主播等级:%.data.anchor_info.live_info.level%)
观众1:>setValue(daka, %[%{daka}+1]%) 观众2:>setValue(daka, %[%{daka}+1]%)
%{daka}% = 0
,那么 %[%{daka}+1]% = 1
,那么执行的命令有可能会变成:观众1:>setValue(daka, 1) 观众2:>setValue(daka, 1)
daka
的值依旧为 1
,而不是 2
。>addValue(daka, 1)
或者语法糖 {daka}++
来替代 >setValue(daka, %[%{daka}+1]%)
,更安全且简洁易懂!观众1:>addValue(daka, 1) -> 变成1 观众2:>addValue(daka, 1) -> 变成2
^1$
,回复:已自动禁言,赠送小心心或关注主播解禁\n>block(%uid%, 1)\n>addGameUser(%uid%)
[%in_game_users%,%origin_gift_name%=小心心]***已解除禁言\n>unblock(%uid%)\n>removeGameUser(%uid%)
[%in_game_users%]*已解除禁言\n>unblock(%uid%)\n>removeGameUser(%uid%)
^开启AI回复$
>execRemoteCommand(开启弹幕回复,0)\n>setValue(reply, 1)\n已开启AI弹幕回复,发送“关闭”结束
^关闭(AI回复)?$
(回复“关闭”两字即可,可不用全打)[%guard%, %{reply}%]>execRemoteCommand(关闭弹幕回复)\n>setValue(reply, 0)
>execRemoteCommand
:运行仅机器人和主播才能用的远程指令,参数2的0
表示不自动回复(因为有自定义的另一个回复,覆盖掉默认的)\n
:多个指令或多条弹幕,用 \n
标记隔开setValue(reply, 1)
:设置变量reply
的值为1,用来判断是否需要关闭[%guard%, %{reply}%]
:舰长且reply
=1,若是则执行后面的,否则不做操作^(签到|打卡)$
,动作:[%{daka_today_%uid%}%]*>您已打过卡 [%living%+1]>打卡成功,您是今天第%[%{daka}%+1]%个,累计%[%{daka_sum_%uid%}%+1]%天\n\ >setValue(daka, %[%{daka}%+1]%)\n\ >setValue(daka_today_%uid%, 1)\n\ >setValue(daka_sum_%uid%, %[%{daka_sum_%uid%}%+1]%)
NEW_DAY
,动作:[%living%+1]>removeValues(daka_today_\d+)\n>setValue(daka, 0)
[%living%+1]
是用来保证即使开启了“仅在直播时回复”也能发送回复的弹幕[ { "anchor_key": "神奇弹幕:AutoReply", "enabled": true, "key": "^(签到|打卡)\\s*([\\((].*|\\d+)?$", "reply": "/// 记录每位用户是第几个打卡以及累计天数\n[%{daka_today_%uid%}%]*>您已打过卡\n[%living%+1]>签到成功,您是今天第%[%{daka}%+1]%个,本月%[%{daka_month_%uid%}%+1]%天\\n\\\n\t>setValue(daka, %[%{daka}%+1]%)\\n\\\n\t>setValue(uname_%uid%, %uname%)\\n\\\n\t>setValue(daka_today_%uid%, 1)\\n\\\n\t>setValue(daka_sum_%uid%, %[%{daka_sum_%uid%}%+1]%)\\n\\\n\t>setValue(daka_month_%uid%, %[%{daka_month_%uid%}%+1]%)\\n\\\n\t>setValue(daka_keep_%uid%, %[%{daka_keep_%uid%}%+1]%)\\n\\\n\t>setValue(integral_%uid%, %[%{integral_%uid%}%+1000]%)\\n\\\n\t>triggerEvent(DAKA_MONTH_%[%{daka_month_%uid%}%+1]%)" }, { "anchor_key": "神奇弹幕:AutoReply", "enabled": true, "key": "^(查询(打卡|签到)|(打卡|签到)查询)$", "reply": "[%living%+1]连续%[%{daka_keep_%uid%}%]%天,本月%[%{daka_month_%uid%}%]%天,累计%[%{daka_sum_%uid%}%]%天" }, { "action": "/// 重置每天打卡的人数\n[%living%+1]>setValue(daka, 0)\\n\\ // 重置今日打卡人数\n\t>removeValuesIf(^daka_keep_(\\d+)$, [!_{daka_today__$1_}_])\\n\\ // 未连续签到断开\n\t>removeValues(daka_today_\\d+) // 重置每人是否打卡", "anchor_key": "神奇弹幕:EventAction", "enabled": true, "event": "NEW_DAY_FIRST" }, { "action": "/// 重置每月打卡天数\n[%living%+1]>setValues(daka_month_\\d+, 0)", "anchor_key": "神奇弹幕:EventAction", "enabled": true, "event": "NEW_MONTH_FIRST" }, { "action": "您已打卡满21天,可找主播领小礼物~", "anchor_key": "神奇弹幕:EventAction", "enabled": true, "event": "DAKA_MONTH_21" } ]
LIVE
,动作:>connectNet(https://push.xuthus.cc/group/[skey]?c=[开播消息])
[skey]
为您的酷推Skey,[开播消息]
按服务格式自定义PK_BATTLE_PRE
,动作:>setValue(pk_ceng, 0)
SEND_GIFT
,动作:[%pking%, %{pk_ceng}%=0, %gift_gold% >= 100000, %gift_num%=1]>setValue(pk_ceng, 1)\n>sendGift(20004, 1)
PK_BATTLE_END
,动作:[%{pk_ceng}%=0]>setValue(pk_ceng, 1)\n>postData(https://api.live.bilibili.com/xlive/lottery-interface/v2/pk/join, id=%pk_id%&roomid=%room_id%&type=pk&csrf_token=%csrf%&csrf=%csrf%&visit_id=)
PK_MATCH_INFO
,将在大乱斗开始的时候,获取对面直播间的信息。https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom?room_id=您的房间ID
的结果,其 data
中的值。%.anchor_info.base_info.uname%
%.anchor_info.medal_info.medal_name%
%.guard_info.count%
%.anchor_info.relation_info.attention%
%.anchor_info.medal_info.fansclub%
%.anchor_info.live_info.level%
%.anchor_info.live_info.score%
%.room_info.title%
%.room_info.area_name%
匹配到:%.anchor_info.base_info.uname%,%.guard_info.count%舰长,%.anchor_info.relation_info.attention%粉丝
PK_END
,动作:[%level%>0]>setValue(winCount, %[%{winCount}%+1]%)\n>triggerEvent(winCountReport) [%level%<0]>setValue(winCount, 0)
winCountReport
,动作:[%{winCount}%>=3]目前连胜场数:%{winCount}%
>setValue(winCount,5)
NEW_DAY_FIRST
,动作:>setValue(pk_win, 0)
RECEIVE_PRIVATE_MSG
:[%.last_msg.msg_type% != 1]*** // 忽略系统通知等无关消息 [[[%text% ~ ^设置我的]]]>triggerReply(%text%) [[[%text% ~ ^兑换奖品]]]>triggerReply(%text%) [[[%text% ~ ^我的信息$]]]>sendPrivateMsg(%uid%, 名字:%{info/name_%uid%}%,地址:%{info/addr_%uid%}%,号码:%{info/num_%uid%}%)
^设置我的(.+)[::](.+)
(^
在正则表达式中为开头的意思):[[[%$1% = 名字]]]>setValue(info/name_%uid%, %$2%)\n>sendPrivateMsg(%uid%, 已设置您的名字为:%$2%) [[[%$1% = 地址]]]>setValue(info/addr_%uid%, %$2%)\n>sendPrivateMsg(%uid%, 已设置您的地址为:%$2%) [[[%$1% = 号码]]]>setValue(info/num_%uid%, %$2%)\n>sendPrivateMsg(%uid%, 已设置您的号码为:%$2%)
^兑换奖品[::](.+)$
:[[["%{info/name_%uid%}%" = ""]]]*>sendPrivateMsg(%uid%, "请先发送“设置我的名字:xxx”来设置收件人姓名") [[["%{info/num_%uid%}%" = ""]]]*>sendPrivateMsg(%uid%, "请先发送“设置我的号码:xxx”来设置手机号码") [[["%{info/addr_%uid%}%" = ""]]]*>sendPrivateMsg(%uid%, "请先发送“设置我的地址:xxx”来设置收件地址") [[[%$1% = 手作; %$1% = 红包]]]>appendFileLine(兑奖.csv, \ %uid%, %uname%, %$1%, %{info/name_%uid%}%, %{info/num_%uid%}%, %{info/addr_%uid%}%, %>time(yyyy-MM-dd hh:mm)%)\n\ >sendPrivateMsg(%uid%, 操作成功)
兑奖.csv
文件可直接使用 Excel 打开、修改,或另存为 Excel 表格文件。>csvEachLine(兑奖.csv, >sendPrivateMsg(\%$1\%, 【发货提醒】您的“\%$3\%”已发货~)%n%>delay(3000))
%$1%
读取,又因为是在 >csvEachLine
中调用,加上反斜杠 \
转义)和奖品(第三列),向相应的用户发送私信。>delay(3000)
表示发送私信之间间隔 3 秒,瞬间大量发送私信会导致被封禁。%.key1.key2.key3%
这样的形式来获取。另外,通过接口附加上了“sender”字段,可获取发送者的信息(API不稳定,不一定获取到)。具体示例如下(省略了部分不常用数据):{ "talker_id": 324495090, // 用户ID "session_type": 1, "at_seqno": 0, "top_ts": 0, "group_name": "", "group_cover": "", "is_follow": 1, "is_dnd": 0, "ack_seqno": 193772296863792, "ack_ts": 1647245795072485, "session_ts": 1647309089148477, "unread_count": 6, // 最后一条消息。例如获取消息类型:%.last_msg.msg_type% "last_msg": { "sender_uid": 324495090, "receiver_type": 1, "receiver_id": 20285041, "msg_type": 1, // 消息类型,1 用户私信 "content": "{\"content\":\"测试消息\"}", "msg_seqno": 194835318046736, "timestamp": 1647309089, "at_uids": null, "msg_key": 7075138663693631915, "msg_status": 0, "notify_code": "" }, "group_type": 0, "can_fold": 0, "status": 0, "max_seqno": 194835318046736, "new_push_msg": 0, "setting": 0, "is_guardian": 0, "is_intercept": 0, "is_trust": 0, "system_msg_type": 0, "live_status": 0, "biz_msg_unread_count": 0, // 发送者信息(视网络,可能获取不到) "sender": { "code": 0, "message": "0", "ttl": 1, "data": { "mid": 324495090, "name": "般若菠萝包rollora", "sex": "女", "face": "http://i0.hdslb.com/bfs/face/63340c49aa7915426f4ba5019cd27a5cbec098b8.jpg", "face_nft": 0, "sign": "自由人,生活向主播,经纪人", "rank": 10000, "level": 5, "jointime": 0, "moral": 0, "silence": 0, "coins": 0, "fans_badge": true, "fans_medal": { "show": false, "wear": false, "medal": null }, "is_followed": true, "live_room": { "roomStatus": 1, "liveStatus": 0, "url": "https://live.bilibili.com/11046586?broadcast_type=0&is_room_feed=1", "title": "房间标题", "cover": "http://i0.hdslb.com/bfs/live/new_room_cover/5987df8547248533f87bcbb40926742d8ce07a17.jpg", "roomid": 11046586, "roundStatus": 0, "broadcast_type": 0, "watched_show": { "switch": true, "num": 220, "text_small": "220", "text_large": "220人看过", "icon": "https://i0.hdslb.com/bfs/live/a725a9e61242ef44d764ac911691a7ce07f36c1d.png", "icon_location": "", "icon_web": "https://i0.hdslb.com/bfs/live/8d9d0f33ef8bf6f308742752d13dd0df731df19c.png" } }, } } },
WEBSOCKET_CMDS
,动作:[%text%=SQUAT]>sendToSockets(SQUAT, {"cmd":"SQUAT", "data":%{squat}%})
初始化蹲起数量
的动作(事件建议留空,手动点击发送按钮):>setValue(squat, 0)\n>sendToSockets(SQUAT, {"cmd":"SQUAT", "data":0})
蹲起数量+1
的动作(事件自选,可空着手动点发送来增加次数):>setValue(squat, %[%{squat}%+1]%)\n\ >sendToSockets(SQUAT, {"cmd":"SQUAT", "data":%[%{squat}%+1]%})
www/squat.html
文件,写入:<head> <title>神奇弹幕蹲起</title> <script src="js/jquery.js"></script> <style type="text/css"> .card { background-color: #fff; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); transition: 0.3s; /* width: 40%; */ border-radius: 5px; padding-left: 20px; padding-right: 20px; } .card:hover { box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2); } </style> </head> <body> <div class="card" style="display:inline-block"> <h1 id='count'>蹲起个数:0</h1> </div> <script type="text/javascript"> $(document).ready(function () { var ws = new WebSocket("ws://__DOMAIN__:__WS_PORT__"); ws.onopen = function () { ws.send('{"cmd":"cmds", "data":["SQUAT"]}'); }; ws.onmessage = function (e) { var json = JSON.parse(e.data); var cmd = json['cmd']; switch (cmd) { case 'SQUAT': console.log(json); var count = parseInt(json['data']); // 这就是个数 $("#count").html('蹲起个数:' + count); break; } }; }); </script> </body>
localhost:5520/squat.html
(域名端口按照设置的来),显示蹲起数量:0
。var ws = new WebSocket("ws://__DOMAIN__:__WS_PORT__"); ws.onopen = function() { ws.send('{"cmd":"cmds", "data":["SONG_LIST"]}'); };
__DOMAIN__::__WS_PORT__
会自动替换为用户设置的 域名:端口+1
,若未设置,则默认为 localhost:5521
。onopen
方法中,必须向服务端发送格式为{"cmd": "cmds","data":[需要接收的cmd列表]}
的 JSON 数据,其中 cmd列表
为接收服务端的哪些命令的字符串数组(相当于白名单),可用事件中的部分命令。SONG_LIST
:点歌列表LYRIC_LIST
:歌词CURRENT_SONG
:正在播放的歌曲LIVE_ALL_GIFTS
:本场直播所有礼物(同一人同一礼物合并),仅接受一次SONG_LIST
并显示在 DOM 节点中:<ol id="songs" class="live numbers"> </ol> <!-- 被修改的ul -->
ws.onmessage = function(e) { console.log(e.data); // 打印接收的json格式,类型太多,就不一一说明了 var json = JSON.parse(e.data); var cmd = json['cmd']; switch (cmd) { case 'SONG_LIST': var songs = json['data']; // 歌曲对象组成的数组 var olHtml = ''; for (var i = 0; i < songs.length; i++) { var song = songs[i]; // 歌曲对象,可获取歌名、歌手、用户等 olHtml += '<li>' + song['name'] + "</li>"; } $("#songs").html(olHtml); break; } };
ext_settings.ini
中。使用相应的 cmd 实现功能,无需“解锁安全限制”。SET_CONFIG
:在网页中发送该 cmd 的 json,将会保存配置。 group
为保存的分组,读取时传入该参数可获取该分组下的所有配置。建议一个应用的配置都保存到同一个分组下。{ "cmd": "SET_CONFIG", "group": "test", "data": { "key1": 123, "key2": "某个值", "key3": 10.08, "key4": false } }
GET_CONFIG
:返回同样的 cmd,data 中会包含配置的键值对{ "cmd": "GET_CONFIG", "group": "test", "data": ["key1", "key2", "key3", "key4", "key5"] }
data
或留空 "data": []
,会返回该 group 下的所有配置。magical_danmaku.js
,添加 function readConfig(data)
,其中的形参 data
就是返回的 JSON 的 data,可直接读取里面的数值。SET_CONFIG
为例,可能会返回 JSON:{ "cmd": "GET_CONFIG", "data": { "key1": 123, "key2": "某个值", "key3": 10.08, "key4": false, "key5": null } }
GET_INFO
格式的cmd,则会通过内置解释器将一些变量输出为响应的真实数值(都是字符串格式),并按发送的格式返回:{ "cmd": "GET_INFO", "data": { "key1": "key1表达式", "key2": "key2表达式" }
function readInfo(data)
,其中形参 data
就是返回的 JSON 中的 data。function socketInited() { var json = { cmd: "GET_INFO", data: { room_id: "%room_id%", title : "%room_name%", pk : "%pking%" } } appWs.send(JSON.stringify(json)); } function readInfo(data) { roomId = data['room_id']; // 获取到的房间ID title = data['title']; // 房间标题 pking = data['pking']; // 是否正在PK }
{ "cmd": "GET_INFO", "data": { "room_id": "123456", "title": "标题", "pk": "0" } }
扩展-网络服务-解锁安全限制
方有效(默认关闭)。{ "cmd": cmd类型, "data": 数据 }
cmd类型
如下(不分大小写):cmds
get_config
set_config
forward
:将 data
中的数据发送给其他 socket,data
中要同样再包含一层 cmd
和 data
。完整 JSON 如下:{ "cmd": "forward", "data": { "cmd": "[转发的命令]", "data": "[转发数据]" } }
set_value
:修改主程序的原始配置,重启主程序生效。可以有两种形式:// 单独修改一项设置 { "cmd": "set_value", "data": { "key": "[key]", "value": [value] // 可以是字符串,也可以是整数 } }
// V4.7.2新增,同时修改多项设置 { "cmd": "set_value", "data": { "key1": [value1], "key2": [value2], "key3": [value3] } }
send_msg
:使主程序发送弹幕,data
为弹幕字符串,使用 \\n
来分隔多条弹幕;不会解析变量,而是直接发送出去{ "cmd": "send_msg", "data": "要发送的弹幕1\\n弹幕2\\n弹幕3" }
send_variant_msg
:使主程序发送带变量的弹幕或命令,例如 %{key}%
;需要用户信息的例如 %uid%
均不可使用。{ "cmd": "send_variant_msg", "data": "数量:%{count}%" }
/api/header?uid=123456
,可直接用于 <img>
标签<img src="http://__DOMAIN__:__PORT__/api/header?uid=123456" />
/api/netProxy?url=网址
,可解决本地请求无法跨域问题;其中 网址
若带有参数,则建议进行 URL 编码。请求时使用 GET、POST 等不同方法、设置不同 content-type,都会响应转移到代理中,并自动设置当前登录账号的 Cookies。$.ajax({ url: "http://__DOMAIN__:__PORT__/api/netProxy?url=http://api.live.bilibili.com/xlive/web-room/v1/giftPanel/giftConfig?platform=pc", async: false, dataType: "JSON", success: function (data) { giftList = data["data"]["list"]; } });
url
之外的参数都会设置到请求的 header 中,如:/api/netProxy?url=xxx&referer=xxx&content-type=xxx
/api/event?event=事件名&data=url编码(json)
,会触发指定事件如 SEND_GIFT
。若使用 post 方式,data 部分可直接使用 json 来发送而不需要 url 编码。www
中,每一套小程序(可以是多个网页)对应 www 中一个文件夹,并带有 package.json 文件(旧版为 info.json),可被神奇弹幕识别,添加到“网络服务”的“已安装扩展”中,并添加一些快捷按钮。{ "name": "点歌姬", // 扩展整体名字 "min_version": "4.4.0", // 能用的神奇弹幕最低版本,过低会报警告 "author": "小乂", // 作者名字 "list": [ // 允许多个网页,list中一项一个 { "name": "弹幕点歌列表", // 这是显示出来的名字 "url": "index.html", // 相对于主机地址的URL路径 "desc": "显示弹幕点歌的实时列表,播放完毕后自动移除", // 简单描述与说明 "author": "作者名", // (可空)单独的作者名字 "css": "list.css", // (可空)便于用户修改的CSS文件相对于www文件夹的路径 "css_custom": "list_custom.css", // (可空)用户自定义CSS,修改后会覆盖上面一项 "cover": "cover.png", // (可空)扩展封面图片,默认为 cover.png "code": [], // (可空)有些弹幕交互程序需要添加的代码,代码块菜单“复制+继续复制”后粘贴到此处 "config": "config.html", // (可空)扩展的配置页面 "homepage": "http://xxx", // (可空)主页链接 "contact": "http://xxx", // (可空)联系作者 "reward": "http://xxx", // (可空)打赏链接 "dir": "images", // (可空)打开某一文件夹,比如图片资源,用于用户替换 "file": "result.txt", // (可空)打开某一文件,比如保存的抽奖结果 "menus": [ // (可空)自定义扩展的右键菜单 { "name": "自定义菜单", "url": "http://xxx", "code": "" // 点击这个菜单项要执行的代码/弹幕 } ] }, { "name": "当前歌曲名字", "url": "/music/playing.html", "css": "/music/playing.css", "desc": "点歌姬正在播放的歌曲的名字" }, /* ... */ ] }
菜单—调试—调试模式
,开启后每次有人进来都会尝试欢迎,有以下几种情况:[xxx]****
的格式菜单—调试—最后一次候选弹幕
(手速要快,不然会被新弹幕覆盖),查看变量被替换的内容,以及弹幕随机发送的候选项,检查逻辑条件是否有误。