哔哩哔哩工具合集-开发中

注:练手作品,多多包涵,不接受恶意差评,有问题群内咨询(Q群1031014013):一键播放所有视频;一键拉黑。。。(友情天选群746790091 )

当前为 2021-03-05 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/422731/907383/%E5%93%94%E5%93%A9%E5%93%94%E5%93%A9%E5%B7%A5%E5%85%B7%E5%90%88%E9%9B%86-%E5%BC%80%E5%8F%91%E4%B8%AD.js

  1. // ==UserScript==
  2. // @name 哔哩哔哩工具合集-开发中
  3. // @description 注:练手作品,多多包涵,不接受恶意差评,有问题群内咨询(Q群1031014013):一键播放所有视频;一键拉黑。。。(友情天选群746790091 )
  4. // @namespace http://tampermonkey.net/
  5. // @version 1.1.7
  6. // @description try to take over the world!
  7. // @author 荒年(QQ:2019676120)
  8. // @match *://space.bilibili.com/*
  9. // @require https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js
  10. // @resource animate http://cdn.javaex.cn/javaex/pc/css/animate.css
  11. // @resource common http://cdn.javaex.cn/javaex/pc/css/common.css
  12. // @resource defaultCss http://cdn.javaex.cn/javaex/pc/css/skin/default.css
  13. // @grant unsafeWindow
  14. // @grant GM_getValue
  15. // @grant GM_setValue
  16. // @grant GM_xmlhttpRequest
  17. // @grant GM_getResourceText
  18. // @grant GM_openInTab
  19. // @grant GM_addStyle
  20. // @run-at document-idle
  21. // @license MIT License
  22. // @namespace http://tampermonkey.net/
  23. // ==/UserScript==
  24.  
  25.  
  26. GM_addStyle(`
  27. #left_navbar{
  28. z-index: 1000;
  29. position: absolute;
  30. top: 100px;
  31. left: 5px;
  32. }
  33. button[hnBtn="btn_open"] {
  34. z-index: 1001;
  35. z-index: 1000px;
  36. position: absolute;
  37. top: 58px;
  38. left: 220px;
  39. }
  40. .javaex-panel.javaex-panel-right.javaex-animated-zoom-in {
  41. top: 60px;
  42. }
  43. .javaex-menu-container {
  44. border: 1px solid #eee;
  45. }
  46. .javaex-panel-box p {
  47. text-align: center;
  48. background: #fb7299;
  49. }
  50. .fontbold{
  51. color: #00a1d6;
  52. font-weight: bold;
  53. cursor: pointer;
  54. }
  55. `);
  56.  
  57. let Live_info = {
  58. author_uid: 99439379,
  59. room_id: undefined,
  60. uid: undefined,
  61. blocked: undefined,
  62. csrf_token: undefined,
  63. visit_id: undefined,
  64. rnd: undefined,
  65. ruid: undefined,
  66. uname: undefined,
  67. user_level: undefined,
  68. ruid: undefined,
  69. };
  70.  
  71. let BILIBLI_PATH = {
  72.  
  73. "passport": "https://passport.bilibili.com",
  74. "api": "https://api.bilibili.com",
  75. "video": "https://www.bilibili.com/video/",
  76. "single_unread": "http://api.vc.bilibili.com/"
  77. }
  78.  
  79. let BILIBILI_URL = {
  80. // 导航栏用户信息
  81. "nav": BILIBLI_PATH.api + "/x/web-interface/nav",
  82. }
  83.  
  84. let BiliData = {
  85. login_code: null,
  86. login_message: "",
  87. LoginData: {},
  88. CoinLog: {},
  89. Unread: null,
  90. Video: {},
  91. replyAction: {},
  92. upCard: {},
  93. BVList: [],
  94. }
  95.  
  96. let script2 = document.createElement('script');
  97. script2.setAttribute('type', 'text/javascript');
  98. script2.src = "https://cdn.jsdelivr.net/gh/java-xiaoyi/HNGG-RES@main/javaex/pc/js/javaex-formVerify.js";
  99. document.documentElement.appendChild(script2);
  100.  
  101. let script = document.createElement('script');
  102. script.setAttribute('type', 'text/javascript');
  103. script.src = "https://cdn.jsdelivr.net/gh/java-xiaoyi/HNGG-RES@main/javaex/pc/js/javaex.js";
  104. document.documentElement.appendChild(script);
  105.  
  106. window.onload = function () {
  107.  
  108. //界面显示
  109. init();
  110.  
  111. document.getElementById("getAtMsg").click();
  112.  
  113. }
  114.  
  115.  
  116. function init() {
  117.  
  118. Live_info.csrf_token = HNTOOL.getCookie("bili_jct");
  119. Live_info.uid = HNTOOL.getCookie("DedeUserID");
  120.  
  121. addStyle();
  122. addSetPage();
  123.  
  124. $("#getCoinLog").bind("click", async function () {
  125.  
  126.  
  127. if (HNAPI.getCoinLog()) {
  128.  
  129. await HNTOOL.Sleep(500);
  130. let html = '';
  131. html += '<div class="javaex-panel-box" style="width: 250px;">';
  132. html += ' <ul>';
  133. html += ` <p style="color: #FFF;">硬币使用记录</p>`;
  134.  
  135. BiliData.CoinLog.list.forEach(function (item) {
  136.  
  137. let BV = item.reason.replace(/[^a-z0-9]+/ig, "");
  138. if (BV.indexOf("BV") != -1) {
  139. html += `<li><a href="${BILIBLI_PATH.video}${BV}">${item.reason}${item.delta}币 ${item.time}</a> </li> `;
  140. }
  141. html += `<li>${item.reason}${item.delta}币 ${item.time}</li> `;
  142.  
  143.  
  144. });
  145. html += ' <hr class="javaex-divider"></hr>';
  146. html += ' </ul>';
  147. html += '</div>';
  148.  
  149. javaex.panel(this, {
  150. position: "right",
  151. //offsetTop: "104",
  152. content: html
  153. });
  154. javaex.tip({
  155. content: "获取用户成功!",
  156. type: "success"
  157. });
  158.  
  159. } else {
  160. javaex.tip({
  161. content: "获取硬币记录失败,请稍后重试!",
  162. type: "error"
  163. });
  164. }
  165.  
  166.  
  167. });
  168.  
  169. $("#getUnread").bind("click", async function () {
  170.  
  171. javaex.tip({
  172. content: "获取中,请稍候...",
  173. type: "submit"
  174. });
  175. HNAPI.getUnread();
  176.  
  177.  
  178. });
  179.  
  180.  
  181. $("#likeInDynamicComments").bind("click", async function () {
  182.  
  183. let prid = LocalData.get("likeInDynamic_PRID") == null ? "4015599048" : LocalData.get("likeInDynamic_PRID");
  184. let oid = LocalData.get("likeInDynamic_OID") == null ? "108928314" : LocalData.get("likeInDynamic_OID");
  185.  
  186. let html = '';
  187.  
  188. html += '<div style="padding: 10px 10px 10px 0px;">'
  189. html += '<form id="likeInDynamic_form">'
  190. html += ' <div class="javaex-unit clear">'
  191. html += ' <div class="javaex-unit-left"><p class="subtitle required">评论RPID</p></div>'
  192. html += ' <div class="javaex-unit-right">'
  193. html += ' <input type="text" class="javaex-text" data-type="positive_int" error-msg="评论RPID格式错误"'
  194. html += ` id="likeInDynamic_PRID" value=${prid} placeholder="请输入评论RPID"/>`
  195. html += ' </div>'
  196. html += ' </div>'
  197. html += ' <div class="javaex-unit clear">'
  198. html += ' <div class="javaex-unit-left"><p class="subtitle required">OID</p></div>'
  199. html += ' <div class="javaex-unit-right">'
  200. html += ' <input type="text" class="javaex-text" data-type="positive_int" error-msg="OID格式错误"'
  201. html += ` id="likeInDynamic_OID" value=${oid} placeholder="请输入OID"/>`
  202. html += ' </div>'
  203. html += ' </div>'
  204. html += ' <div class="javaex-unit clear tc">'
  205. html += ' <input type="button" id="likeInDynamic_no" class="javaex-hover-pulse javaex-btn no " value="取消赞"/>'
  206. html += ' <input type="button" id="likeInDynamic_yes" class="javaex-hover-pulse javaex-btn yes" value="点赞"/>'
  207. html += ' </div>'
  208. html += '</form>';
  209. html += '<hr class="javaex-divider"></hr>';
  210. html += '</div>';
  211.  
  212.  
  213. javaex.panel(this, {
  214. position: "right",
  215. content: html
  216. });
  217.  
  218.  
  219. // 监听点击保存按钮事件
  220. $("#likeInDynamic_yes").click(async function () {
  221. // 表单验证函数
  222. if (javaexVerify()) {
  223.  
  224. HNAPI.likeInDynamicComments(+javaex.getSelectVal("#likeInDynamic_OID"), +javaex.getSelectVal("#likeInDynamic_PRID"), 1);
  225. await HNTOOL.Sleep(1000);
  226.  
  227. if (BiliData.replyAction.code == 0) {
  228.  
  229. LocalData.set("likeInDynamic_PRID", javaex.getSelectVal("#likeInDynamic_PRID"));
  230. LocalData.set("likeInDynamic_OID", javaex.getSelectVal("#likeInDynamic_OID"));
  231.  
  232. javaex.tip({content: "评论区点赞成功!", type: "success"});
  233. } else {
  234. javaex.tip({content: "评论区点赞失败!", type: "error"});
  235. }
  236. if (BiliData.replyAction.code == 65006) {
  237. javaex.tip({content: "请勿重复点赞!", type: "error"});
  238. }
  239. }
  240. });
  241.  
  242. // 监听点击返回按钮事件
  243. $("#likeInDynamic_no").click(async function () {
  244.  
  245. if (javaexVerify()) {
  246.  
  247. HNAPI.likeInDynamicComments(+javaex.getLocalStorage("#likeInDynamic_OID"), +javaex.getLocalStorage("#likeInDynamic_PRID"), 0);
  248. await HNTOOL.Sleep(500);
  249.  
  250. if (BiliData.replyAction.code == 0) {
  251.  
  252. javaex.setLocalStorage("likeInDynamic_PRID", javaex.getSelectVal("#likeInDynamic_PRID"));
  253. javaex.setLocalStorage("likeInDynamic_OID", javaex.getSelectVal("#likeInDynamic_OID"));
  254.  
  255. javaex.tip({content: "评论区取消点赞成功!", type: "success"});
  256. } else {
  257. javaex.tip({content: "评论区取消点赞失败!", type: "error"});
  258. }
  259. if (BiliData.replyAction.code == 65006) {
  260. javaex.tip({content: "请勿重复取消点赞!", type: "error"});
  261. }
  262. }
  263. });
  264.  
  265. });
  266.  
  267. $("#biliUserMsg").bind("click", async function () {
  268.  
  269.  
  270. //刷新信息
  271. HNAPI.getUserNav();
  272. await HNTOOL.Sleep(500);
  273.  
  274. let isLogin = "未登录";
  275. let vipType = "无";
  276. //判断是否成功
  277. if (BiliData.login_code == 0) {
  278.  
  279.  
  280. if (BiliData.LoginData.isLogin) {
  281. isLogin = "已登录";
  282. }
  283.  
  284. if (BiliData.LoginData.vipType == 1) {
  285. vipType = "月度大会员";
  286. } else if (BiliData.LoginData.vipType == 2) {
  287. vipType = "年度大会员";
  288. }
  289.  
  290. let html = '';
  291. html += '<div class="javaex-panel-box" style="width: 250px;">';
  292. html += ' <ul>';
  293. html += ` <p style="color: #FFF;">用户信息</p>`;
  294. html += ` <li><a href="https://account.bilibili.com/account/home">当前用户:${BiliData.LoginData.uname}</a> </li> `;
  295. html += ` <li>用户状态:${isLogin} </li> `;
  296. html += ` <li>用户等级:${BiliData.LoginData.level_info.current_level}</li> `;
  297. html += ` <li>升级下一等级需:${BiliData.LoginData.level_info.next_exp - BiliData.LoginData.level_info.current_exp} 经验</li> `;
  298. html += ` <li>UID${BiliData.LoginData.mid} </li> `;
  299. html += ` <li><a href="https://account.bilibili.com/account/coin">硬币:${BiliData.LoginData.money}</a> </li> `;
  300. html += ` <li>节操值:${BiliData.LoginData.moral} </li> `;
  301. html += ` <li>会员:${vipType} </li> `;
  302. html += ' <hr class="javaex-divider"></hr>';
  303. html += ' </ul>';
  304. html += '</div>';
  305.  
  306.  
  307. javaex.panel(this, {
  308. position: "right",
  309. content: html
  310. });
  311.  
  312. javaex.tip({
  313. content: "获取用户成功!",
  314. type: "success"
  315. });
  316.  
  317. } else {
  318. javaex.tip({
  319. content: "获取用户信息失败!",
  320. type: "error"
  321. });
  322. }
  323.  
  324.  
  325. });
  326.  
  327. $("#getAtMsg").bind("click", async function () {
  328.  
  329. if (HNAPI.getMsgfeed("at") && typeof (HNAPI.getMsgfeed("at")) != "undefined") {
  330.  
  331. javaex.tip({
  332. content: "可能中奖了!!!",
  333. type: "success"
  334. });
  335. }
  336. });
  337.  
  338.  
  339. $("#disUser").bind("click", async function () {
  340.  
  341. let html = '';
  342. html += '<div class="javaex-panel-box" style="width: 500px;">';
  343. html += ' <div class="javaex-unit clear">';
  344. html += ' <div class="javaex-unit-left ml-10 mt-10">*拉黑列表</div>';
  345. html += ' <div class="javaex-unit-right mr-10 mt-10">';
  346. html += ' <textarea id="disUser_uidList" class="javaex-desc" placeholder="请填写用户UID,多个用英文逗号,隔开"></textarea>';
  347. html += ' </div>';
  348. html += ' </div>';
  349. html += ' <div class="javaex-unit clear tc">';
  350. html += ' <input type="button" id="disUser_beg" class="javaex-btn yes" value="开始" />';
  351. html += ' </div>';
  352. html += '</div>';
  353.  
  354. javaex.panel(this, {
  355. position: "right",
  356. content: html
  357. });
  358.  
  359. $("#disUser_beg").bind("click", async function () {
  360.  
  361. let disUser_str = javaex.getSelectVal("#disUser_uidList");
  362. let disUser_uidList = disUser_str.split(",");
  363.  
  364. for (const vmid of disUser_uidList) {
  365.  
  366. HNAPI.disUserByUid(vmid);
  367.  
  368. await HNTOOL.Sleep(1500);
  369.  
  370. }
  371.  
  372. });
  373.  
  374. });
  375.  
  376. //
  377. $("#getUpMassage").bind("click", async function () {
  378.  
  379.  
  380. let html = '';
  381.  
  382. html += '<div style="padding: 10px 10px 10px 0px;">'
  383. html += '<form id="getUpMassage_form">'
  384. html += ' <div class="javaex-unit clear">'
  385. html += ' <div class="javaex-unit-left mr-10"><p class="subtitle required">用户uid</p></div>'
  386. html += ' <div class="javaex-unit-left mr-10">'
  387. html += ' <input type="text" class="javaex-text javaex-grid-4" data-type="positive_int" error-msg="用户uid"'
  388. html += ` id="up_uid" value="4578433" placeholder="请输入评论uid"/>`
  389. html += ' </div>'
  390. html += ' <div class="javaex-unit-right mr-10">'
  391. html += ' <input type="button" id="getUpMsg" class="javaex-btn blue" value="查询"/>'
  392. html += ' </div>'
  393. html += ' </div>'
  394. html += ' <div class="javaex-unit clear tc" style="width: 500px;">'
  395. html += ' <table id="upMsgTable" class="javaex-table td-c-1">'
  396. html += ' <thead>'
  397. html += ' <tr><th>内容</th><th>详情</th></tr>'
  398. html += ' </thead>'
  399. html += ' <tbody id="upMsgTbody">'
  400.  
  401. html += ' </tbody>'
  402. html += '</table> '
  403. html += '</div>'
  404. html += '</form>';
  405. html += '<hr class="javaex-divider"></hr>';
  406. html += '</div>';
  407.  
  408.  
  409. javaex.panel(this, {
  410. position: "right",
  411. content: html
  412. });
  413.  
  414. javaex.table({
  415. id: "upMsgTable",
  416. isDragColWidth: true, // 是否允许拖动改变列宽
  417. mode: "overflow", // overflow表示允许使用父容器溢出来调整列的大小
  418. leftFixedColNum: 2, // 左侧固定列数
  419. rightFixedColNum: 1, // 右侧固定列数
  420. sort: {
  421. "1": "create_time", // 4表示第几列(从1开始计)。create_time表示排序字段,回调函数会返回该值
  422. "2": "update_time"
  423. },
  424. sortCallback: function (rtn) {
  425. //console.log(rtn.sortArr);
  426. }
  427. });
  428.  
  429. //
  430. $("#getUpMsg").click(async function () {
  431.  
  432. let temp = HNAPI.getUpCard(parseInt(javaex.getSelectVal("#up_uid")));
  433.  
  434.  
  435. await HNTOOL.Sleep(500);
  436.  
  437.  
  438. if (temp != false) {
  439. let data = BiliData.upCard.data;
  440.  
  441. let html = ``;
  442. html += `<tr><td>用户UID</td><td>${data.card.mid}</td></tr> `
  443. html += `<tr><td>用户等级</td><td>lv${data.card.level_info.current_level}</td></tr> `
  444. html += `<tr><td>用户昵称</td><td>${data.card.name}</td></tr> `
  445. html += `<tr><td>用户性别</td><td>${data.card.sex}</td></tr> `
  446. html += `<tr><td>用户头像</td><td><a href="javascript:;"><img src= ${data.card.face} width="50%"></a></td></tr> `
  447. html += `<tr><td>粉丝数</td><td>${data.follower}</td></tr> `
  448. html += `<tr><td>关注数</td><td>${data.card.friend}</td></tr> `
  449. html += `<tr><td>是否关注此用户</td><td>${data.following}</td></tr> `
  450. html += `<tr><td>用户稿件数</td><td>${data.archive_count}</td></tr> `
  451. html += `<tr><td>用户勋章</td><td>${data.card.nameplate.name}<a href="javascript:;"><img src= ${data.card.nameplate.image} width="50%"></a> </td></tr> `
  452. html += `<tr><td>用户勋章等级</td><td>${data.card.nameplate.level}</td></tr> `
  453. html += `<tr><td>认证信息</td><td>${data.card.Official.title}</td></tr> `
  454.  
  455.  
  456. $("#upMsgTbody").empty();
  457. $("#upMsgTbody").append(html);
  458. }
  459.  
  460.  
  461. });
  462. //点击放大
  463. /* $("img").click(function() {
  464. javaex.dialog({
  465. type : "image", // 弹出层类型
  466. url : $(this).attr("src") // 图片地址
  467. });
  468. });*/
  469.  
  470. });
  471.  
  472.  
  473. $("#addPlay").bind("click", async function () {
  474.  
  475.  
  476. let html = '';
  477.  
  478. html += '<div style="padding: 10px 10px 10px 0px;">'
  479. html += '<form id="getUpMassage_form">'
  480.  
  481. html += ' <div class="javaex-unit clear">'
  482. html += ' <div class="javaex-unit-left"><p class="subtitle required">UID</p></div>'
  483. html += ` <div class="javaex-unit-right" tooltip="请输入用户UID,默认自己" tooltip-pos="up"> `
  484. html += ' <input type="text" class="javaex-text" data-type="positive_int|required" error-msg="请正确输入uid"'
  485. html += ` id="addPlay_uid" value="${Live_info.uid}" placeholder="默认${Live_info.author_uid}"/>`
  486. html += ' </div>'
  487. html += ' </div>'
  488. html += ' <div class="javaex-unit clear">'
  489. html += ' <div class="javaex-unit-left"><p class="subtitle required">BV</p></div>'
  490. html += ' <div class="javaex-unit-right" tooltip="请输入视频BV号 例如BV14r4y1A7Q9 (0表示全部)" tooltip-pos="up">'
  491. html += ' <input type="text" class="javaex-text" data-type="required|english_number" error-msg=""'
  492. html += ` id="addPlay_bv" value="0" placeholder="请输入视频BV号 例如BV14r4y1A7Q9 (0表示全部)"/>`
  493. html += ' </div>'
  494. html += ' </div>'
  495. html += '</form>';
  496. html += ' <div class="javaex-unit clear tc">'
  497. html += ' <button id="addPlay_bgn" class="javaex-btn blue radius-3">开始</button> '
  498. html += ' </div>'
  499. html += '<hr class="javaex-divider"></hr>';
  500. html += '</div>';
  501.  
  502.  
  503. javaex.panel(this, {
  504. position: "right",
  505. content: html
  506. });
  507.  
  508. $("#addPlay_bgn").click(async function () {
  509.  
  510. let MID = javaex.getSelectVal("#addPlay_uid")
  511. let BV = javaex.getSelectVal("#addPlay_bv");
  512. let bvArr = [];
  513. let bvArr2 = [];
  514.  
  515. MID = javaex.ifnull(MID, Live_info.author_uid);
  516.  
  517.  
  518. if (BV == "0") {
  519.  
  520. //1.查询up所有视频BV号 2.发送心跳间隔2s
  521. HNAPI.getUpAllBV(Live_info.author_uid, 1, 2);
  522. await HNTOOL.Sleep(500);
  523. bvArr2 = BiliData.BVList;
  524.  
  525. for (let i = 1; i > 0; i++) {
  526.  
  527. HNAPI.getUpAllBV(MID, i);
  528.  
  529. await HNTOOL.Sleep(500);
  530.  
  531. if (BiliData.BVList.length == 0) {
  532. if (bvArr.length == 0) {
  533. javaex.tip({
  534. content: "该用户无投稿视频,请确认是否有误!",
  535. type: "success"
  536. });
  537. await HNTOOL.Sleep(2000);
  538. }
  539. //bvArr = bvArr.ifnull(bvArr2, bvArr.concat(bvArr2));
  540. bvArr = bvArr.concat(bvArr2);
  541. break;
  542. }
  543.  
  544. bvArr = bvArr.concat(BiliData.BVList);
  545. }
  546.  
  547.  
  548. if (bvArr.length != 0) {
  549.  
  550. for (const emt of bvArr) {
  551.  
  552. HNAPI.playOneVideo(emt.bvid,MID);
  553.  
  554. await HNTOOL.Sleep(2000);
  555.  
  556. }
  557.  
  558. alert("播放完成!!!");
  559.  
  560. }
  561.  
  562.  
  563. } else {
  564. //1.调用点击播放接口
  565. //2.发送心跳
  566.  
  567. await HNTOOL.Sleep(500);
  568.  
  569. HNAPI.playOneVideo(BV);
  570. }
  571.  
  572.  
  573. });
  574.  
  575.  
  576. });
  577.  
  578. }
  579.  
  580.  
  581. let showUnreadMsg = function () {
  582.  
  583. var html = '';
  584. html += '<div class="javaex-panel-box" style="width: 250px;">';
  585. html += ' <ul>';
  586. html += ` <p style="color: #FFF;">用户消息</p>`;
  587. html += ` <li><a href="https://message.bilibili.com/#/at">未读艾特数:${BiliData.Unread.at}</a> </li> `;
  588. html += ` <li><a href="https://message.bilibili.com/#/love">未读点赞数:${BiliData.Unread.like}</a> </li> `;
  589. html += ` <li><a href="https://message.bilibili.com/#/reply">未读回复数:${BiliData.Unread.reply}</a> </li> `;
  590. html += ` <li><a href="https://message.bilibili.com/#/system">未读系统通知数:${BiliData.Unread.sys_msg}</a> </li> `;
  591. html += ` <li><a href="">UP主助手信息数:${BiliData.Unread.up}</a> </li> `;
  592. html += ' <hr class="javaex-divider"></hr>';
  593. html += ' </ul>';
  594. html += '</div>';
  595.  
  596.  
  597. javaex.panel(document.getElementById("getUnread"), {
  598. position: "right",
  599. content: html
  600. });
  601.  
  602. javaex.tip({
  603. content: "查询用户通知成功!",
  604. type: "success"
  605. });
  606.  
  607. }
  608.  
  609. /**
  610. * 检查 艾特信息
  611. * @returns {Promise<void>}
  612. */
  613. let chackAtMsg = async function (items) {
  614.  
  615. await HNTOOL.Sleep(500);
  616.  
  617. if (items != false && typeof (items) != "undefined") {
  618.  
  619.  
  620. var html = '';
  621. html += '<div class="javaex-panel-box" style="width: auto;">';
  622. html += ' <ul>';
  623. html += ` <p style="color: #FFF;">@信息</p>`;
  624. items.forEach(function (item) {
  625.  
  626. var atTime = javaex.dateFormat(item.at_time, 'yyyy-MM-dd HH:mm:ss');
  627.  
  628. html += ` <li>${atTime} <a class="fontbold" href="https://space.bilibili.com/${item.user.mid}">:${item.user.nickname}</a>在动态中艾特了你!</li> `
  629. html += ` <li class="fontbold">内容:${item.item.source_content}</li> `;
  630. html += ` <li><a href="${item.item.uri}">---点击查看详情---</a> </li> `;
  631. html += ' <hr class="javaex-divider"></hr>';
  632. });
  633. html += ' </ul>';
  634. html += '</div>';
  635.  
  636. if (($("#chackList").attr("class")).indexOf("hover") > -1) {
  637. javaex.panel(document.getElementById("getAtMsg"), {
  638. position: "right",
  639. content: html
  640. });
  641. } else {
  642. javaex.panel(document.getElementById("chackList"), {
  643. position: "right",
  644. content: html
  645. });
  646. }
  647.  
  648.  
  649. }
  650.  
  651. }
  652.  
  653.  
  654. let addSetPage = async function () {
  655.  
  656. HNTOOL.Sleep(1000);
  657.  
  658. $('body').append('' +
  659. '<div id="left_navbar">' +
  660. '<div class="javaex-menu-container"> ' +
  661. ' <div id="menu" class="javaex-menu"> ' +
  662. ' <ul> ' +
  663. ' <li class="javaex-menu-item alone hover" > ' +
  664. ' <a href="javaScript:;" style="background: #fb7299;padding-left: 0px;text-align: center;color: #ffffff;font-weight: bold;border-bottom: 1px solid #eee;" ' +
  665. ` tooltip="我是来测试的" tooltip-pos="right">管理中心 v${GM_info.script.version}</a> ` +
  666. ' </li> ' +
  667. ' </ul> ' +
  668. ' <ul> ' +
  669. ' <li class="javaex-menu-item"> ' +
  670. ' <a href="javascript:;">个人中心<i class="icon-angle-down"></i></a> ' +
  671. ' <ul> ' +
  672. ' <li id="biliUserMsg" class="javaex-hover-pulse"><a href="javaScript:;">用户信息</a></li> ' +
  673. ' </ul> ' +
  674. ' </li> ' +
  675. ' <li id="chackList" class="javaex-menu-item"> ' +
  676. ' <a href="javaScript:;">查询<i class="icon-angle-down"></i></a> ' +
  677. ' <ul> ' +
  678. ' <li id="getUpMassage" ><a href="javaScript:;">查询用户详细信息</a></li> ' +
  679. ' <li><a href="javaScript:;">查询每日最热视频【禁用】</a></li> ' +
  680. ' <li id="getAtMsg"><a href="javaScript:;">查询动态艾特信息</a></li> ' +
  681. ' <li id="getCoinLog" class="javaex-hover-pulse"><a href="javaScript:;">查询硬币变化</a></li> ' +
  682. ' <li id="getUnread" class="javaex-hover-pulse"><a href="javaScript:;">查询消息</a></li> ' +
  683. ' </ul> ' +
  684. ' </li> ' +
  685. ' <li class="javaex-menu-item"> ' +
  686. ' <a href="javascript:;">工具<i class="icon-angle-down"></i></a> ' +
  687. ' <ul> ' +
  688. ' <li class="javaex-hover-pulse"><a href="javaScript:;" >移动粉丝勋章【禁用】</a></li> ' +
  689. ' <li id="addPlay" class="javaex-hover-pulse"><a href="javaScript:;" >一键批量播放视频</a></li> ' +
  690. ' <li id="disUser" class="javaex-hover-pulse"><a href="javaScript:;" >一键批量拉黑</a></li> ' +
  691. ' <li id="" class="javaex-hover-pulse" ><a href="javaScript:;">动态评论区点赞【禁用】</a></li> ' +//likeInDynamicComments
  692. ' <li id="HNSetup" class="javaex-hover-pulse" ><span class="icon-cogs" style="font-size:50px;color:#ff0000;"></span><a href="javaScript:;">设置【禁用】</a></li> ' +
  693. ' </ul> ' +
  694. ' </li> ' +
  695.  
  696.  
  697. ' </ul> ' +
  698. ' </div> ' +
  699. '</div>' +
  700. '</div>');
  701. //$("#left_navbar").before('<button hnBtn="btn_open" class="javaex-btn green" onclick="openBar()">点我关闭</button>')
  702.  
  703. javaex.menu({
  704. id: "menu",
  705. isShowAll: false
  706. });
  707.  
  708. }
  709.  
  710.  
  711. let addStyle = function () {
  712. const animate = GM_getResourceText('animate');
  713. const common = GM_getResourceText('common');
  714. const defaultCss = GM_getResourceText('defaultCss');
  715. //const icomoonex = GM_getResourceText('icomoonex');
  716. //const AllCss = animate + common + defaultCss + icomoonex;
  717. const AllCss = animate + common + defaultCss;
  718. const style = document.createElement('style');
  719. style.innerHTML = AllCss;
  720. return document.getElementsByTagName('head')[0].appendChild(style);
  721. }
  722.  
  723. /*-----------------------------------------------点击事件绑定--------------------------------------------------*/
  724.  
  725. /*-----------------------------------------------常用API--------------------------------------------------*/
  726.  
  727. let HNAPI = {
  728.  
  729.  
  730. /**
  731. * //https://api.bilibili.com/x/relation/modify
  732. *
  733. * @param UID
  734. */
  735. disUserByUid:function (vmid) {
  736.  
  737. Ajax.post({
  738. url: BILIBLI_PATH.api + '/x/relation/modify',
  739. data: {
  740. fid: parseInt(vmid),
  741. re_src: 11,
  742. act: 5,
  743. jsonp: "jsonp",
  744. csrf: Live_info.csrf_token,
  745. },
  746. hasCookies: true,
  747. dataType: 'application/x-www-form-urlencoded; charset=UTF-8',
  748. success: responseText => {
  749.  
  750. var json = JSON.parse(responseText);
  751.  
  752. if (json.code != 0) {
  753.  
  754. console.log("拉黑用户失败uid:" + vmid + " 错误信息"+ json.message);
  755. javaex.tip({
  756. content: "拉黑用户失败uid:" + vmid + " 错误信息"+ json.message,
  757. type: "error"
  758. });
  759.  
  760. }else{
  761. console.log("拉黑用户成功 uid:" + vmid);
  762. javaex.tip({
  763. content: "拉黑用户成功 uid:" + vmid,
  764. type: "success"
  765. });
  766. }
  767. }
  768. });
  769.  
  770. },
  771. /**
  772. * http://api.bilibili.com/x/web-interface/view
  773. * @param BV
  774. * 心跳间隔15秒
  775. */
  776. playOneVideo: function (BV,MID) {
  777.  
  778. //1.调用点击播放接口 https://api.bilibili.com/x/click-interface/click/web/h5
  779. Ajax.post({
  780. url: BILIBLI_PATH.api + "/x/click-interface/click/web/h5",
  781. hasCookies: true,
  782. dataType: 'application/x-www-form-urlencoded; charset=UTF-8',
  783. data: {
  784.  
  785. "bvid": BV,
  786. "part": 1,
  787. "mid": Live_info.uid,
  788. "lv": 2,
  789. "jsonp": "jsonp",
  790. "type": 3,
  791. "sub_type": 0
  792. },
  793. success: responseText => {
  794.  
  795. let json = JSON.parse(responseText);
  796.  
  797. if (/^{"code":0/.test(responseText)) {
  798. //发送一次心跳
  799. HNAPI.sendHeartbeat(BV,MID);
  800.  
  801. } else {
  802. javaex.tip({
  803. content: "视频" + data.bvid + "播放失败!" + json.message,
  804. type: "error"
  805. });
  806. }
  807. }
  808. })
  809.  
  810.  
  811. },
  812.  
  813. //上报视频播放心跳(web端)
  814. /**
  815. * http://api.bilibili.com/x/click-interface/web/heartbeat
  816. * @param json
  817. */
  818. sendHeartbeat: function (bvid,MID) {
  819.  
  820. Ajax.post({
  821. url: BILIBLI_PATH.api + "/x/click-interface/web/heartbeat",
  822. hasCookies: true,
  823. dataType: 'application/x-www-form-urlencoded; charset=UTF-8',
  824. //aid=756988764&bvid=BV1wr4y1P782&cid=304166326&page=1
  825. data: {
  826. "bvid": bvid,
  827. "type": 3,
  828. "dt": 2,
  829. "played_time": HNTOOL.random(12, 40),
  830. "realtime": HNTOOL.random(12, 40),
  831. "play_type": 0
  832. },
  833. success: responseText => {
  834.  
  835. if (/^{"code":0/.test(responseText) && MID != Live_info.author_uid) {
  836.  
  837. javaex.tip({
  838. content: "视频BV" + bvid + "播放一次!",
  839. type: "success"
  840. });
  841. }
  842. }
  843. })
  844.  
  845. },
  846.  
  847. //获取up所有投稿视频
  848. /**
  849. * https://api.bilibili.com/x/space/arc/search?mid=99439379&ps=30&tid=0&pn=1&keyword=&order=pubdate&jsonp=jsonp
  850. * @param mid
  851. */
  852. getUpAllBV: function (mid, pn, ps) {
  853. ps = (ps === undefined ? 30 : ps); // a默认值为1
  854. Ajax.get({
  855. url: BILIBLI_PATH.api + '/x/space/arc/search',
  856. queryStringsObj: {
  857. mid: mid,
  858. tid: 0,
  859. order: 'pubdate',
  860. jsonp: 'jsonp',
  861. pn: pn,
  862. ps: ps
  863. },
  864. hasCookies: true,
  865. success: responseText => {
  866.  
  867. var json = JSON.parse(responseText);
  868.  
  869. if (json.code != 0) {
  870.  
  871. javaex.tip({
  872. content: "获取up所有投稿视频失败!" + json.message,
  873. type: "success"
  874. });
  875.  
  876. } else {
  877. BiliData.BVList = json.data.list.vlist;
  878.  
  879. }
  880. }
  881. });
  882.  
  883. },
  884.  
  885.  
  886. /**
  887. *
  888. * @param path
  889. * @param data
  890. * @param saveObj
  891. * @param Func
  892. */
  893. publicGet: function (path, queryStringsObj) {
  894.  
  895. if (typeof (queryStringsObj) != "undefined") {
  896. queryStringsObj = {};
  897. }
  898. Ajax.get({
  899. url: BILIBLI_PATH.api + path,
  900. queryStringsObj: queryStringsObj,
  901. hasCookies: true,
  902. success: responseText => {
  903.  
  904. let json = JSON.parse(responseText);
  905. if (chackCode(json.code) && json.code == 0) {
  906.  
  907. return json.data;
  908. }
  909.  
  910. return false;
  911.  
  912. }
  913. })
  914.  
  915. },
  916.  
  917. /**
  918. * 导航栏用户信息
  919. */
  920. getUserNav: async function () {
  921.  
  922. GM_xmlhttpRequest({
  923. method: "GET",
  924. url: BILIBLI_PATH.api + "/x/web-interface/nav",
  925. //timeout:3000,
  926. onload: function (response) {
  927.  
  928. let json = JSON.parse(response.response);
  929. console.log(json);
  930. BiliData.login_code = json.code;
  931. BiliData.login_message = json.message;
  932. BiliData.LoginData = json.data;
  933.  
  934. }
  935. });
  936.  
  937. },
  938.  
  939. /**
  940. * 获取某up详细信息
  941. * http://api.bilibili.com/x/web-interface/card
  942. */
  943. getUpCard: function (mid) {
  944.  
  945. Ajax.get({
  946. url: BILIBLI_PATH.api + '/x/web-interface/card',
  947. queryStringsObj: {
  948. mid: mid,
  949. photo: false
  950. },
  951. hasCookies: true,
  952. success: responseText => {
  953.  
  954. var json = JSON.parse(responseText);
  955.  
  956. if (json.code != 0) {
  957.  
  958. javaex.tip({
  959. content: "查询失败!" + json.message,
  960. type: "success"
  961. });
  962. return false;
  963. } else {
  964. BiliData.upCard = json;
  965.  
  966. }
  967.  
  968.  
  969. }
  970. })
  971.  
  972. },
  973.  
  974. /**
  975. *
  976. * @param uid 用户uid
  977. * @param ps 每页视频个数 默认30个
  978. * @param pn 第几页
  979. */
  980. getUpAllVideo: function (uid, ps, pn) {
  981.  
  982. },
  983. getChallenge: async function () {
  984.  
  985.  
  986. },
  987. /**
  988. * 硬币记录
  989. * @returns {Promise<void>}
  990. */
  991. getCoinLog: async function () {
  992.  
  993. GM_xmlhttpRequest({
  994. method: "GET",
  995. url: BILIBLI_PATH.api + "/x/member/web/coin/log",
  996. //url: "http://api.bilibili.com/x/member/web/coin/log",
  997. onload: function (response) {
  998.  
  999. let json = JSON.parse(response.response);
  1000. if (json.code == 0) {
  1001.  
  1002. console.log("硬币记录" + json);
  1003. BiliData.CoinLog = json.data;
  1004.  
  1005. return true;
  1006. }
  1007.  
  1008. }
  1009. });
  1010. },
  1011. /**
  1012. * 未读消息数 http://api.bilibili.com/x/msgfeed/unread
  1013. * @returns {Promise<void>}
  1014. */
  1015. getUnread: async function () {
  1016.  
  1017. Ajax.get({
  1018. url: BILIBLI_PATH.api + "/x/msgfeed/unread",
  1019. hasCookies: true,
  1020. success: responseText => {
  1021.  
  1022. let json = JSON.parse(responseText);
  1023. if (chackCode(json.code) && json.code == 0) {
  1024.  
  1025. BiliData.Unread = json.data;
  1026. showUnreadMsg();
  1027. }
  1028.  
  1029. return false;
  1030.  
  1031. }
  1032. })
  1033.  
  1034. /* GM_xmlhttpRequest({
  1035. method: "GET",
  1036. url: BILIBLI_PATH.api + "/x/msgfeed/unread",
  1037. onload: function (response) {
  1038.  
  1039. let json = JSON.parse(response.response);
  1040.  
  1041. if (chackCode(json.code) && json.code == 0) {
  1042.  
  1043. BiliData.Unread = json.code;
  1044. showUnreadMsg();
  1045.  
  1046. }
  1047.  
  1048. }
  1049. });*/
  1050. },
  1051. /**
  1052. *
  1053. * @param type reply:回复我的 at @我的
  1054. */
  1055. getMsgfeed: function (type) {
  1056. Ajax.get({
  1057. url: BILIBLI_PATH.api + '/x/msgfeed/' + type,
  1058. queryStringsObj: {
  1059. build: 0,
  1060. mobi_app: 'web'
  1061. },
  1062. hasCookies: true,
  1063. success: responseText => {
  1064.  
  1065. var json = JSON.parse(responseText);
  1066.  
  1067. if (json.code != 0 || !json.data.cursor.is_end || json.data.items == null) {
  1068. return false;
  1069. } else {
  1070. chackAtMsg(json.data.items);
  1071.  
  1072. return true;
  1073. }
  1074.  
  1075.  
  1076. }
  1077. })
  1078.  
  1079. },
  1080.  
  1081. /** 未读消息数 http://api.bilibili.com/x/space/arc/search?mid=99439379&pn=1&ps=5
  1082. * @returns {Promise<void>}
  1083. */
  1084. getUnrewad: async function () {
  1085.  
  1086. GM_xmlhttpRequest({
  1087. method: "GET",
  1088. data: {
  1089. "mid": 99439379,
  1090. "pn": 1,
  1091. "ps": 5,
  1092. },
  1093. url: BILIBLI_PATH.api + "/x/space/arc/search",
  1094. onload: function (response) {
  1095.  
  1096. let json = JSON.parse(response.response);
  1097. if (json.code == 0) {
  1098.  
  1099. BiliData.Video = json.data;
  1100. console.log("未读消息数" + json);
  1101. }
  1102.  
  1103. }
  1104. });
  1105. },
  1106.  
  1107. /** 动态评论区点赞 https://api.bilibili.com/x/v2/reply/action
  1108. * @param {number} oid
  1109. * @param {nbumber} rpid
  1110. * @param {number} action
  1111. * @returns {Promise<void>}
  1112. * type: 11
  1113. * ordering: heat
  1114. * jsonp: jsonp
  1115. * csrf: 54a******* CSRF Token(位于cookie)
  1116. */
  1117.  
  1118. likeInDynamicComments: async function (oid, rpid, action) {
  1119.  
  1120.  
  1121. Ajax.post({
  1122. url: BILIBLI_PATH.api + "/x/v2/reply/action",
  1123. hasCookies: true,
  1124. dataType: 'application/x-www-form-urlencoded; charset=UTF-8',
  1125. data: {
  1126. "oid": oid,
  1127. "type": 11,
  1128. "rpid": rpid,
  1129. "action": action,
  1130. "ordering": "heat",
  1131. "jsonp": "jsonp",
  1132. "csrf": Live_info.csrf_token,
  1133. },
  1134. success: responseText => {
  1135.  
  1136. if (/^{"code":0/.test(responseText)) {
  1137.  
  1138. BiliData.replyAction = JSON.parse(responseText);
  1139. console.log("点赞成功!" + responseText);
  1140. }
  1141. }
  1142. })
  1143.  
  1144. },
  1145.  
  1146.  
  1147. }
  1148.  
  1149. /*-----------------------------------------------常用工具函数--------------------------------------------------*/
  1150.  
  1151.  
  1152. let HNTOOL = {
  1153.  
  1154. /**
  1155. * 获取cookie 中某个键对应的值
  1156. * @param name
  1157. */
  1158.  
  1159. getCookie: function (name) {
  1160. let arr = document.cookie.match(new RegExp("(^| )" + name + "=([^;]*)(;|$)"));
  1161. if (arr != null) return unescape(arr[2]);
  1162. return false;
  1163. },
  1164. /**
  1165. * 得到一个字符串数组的中随机一个
  1166. * @param {List} list
  1167. */
  1168. getRandomWordOfList: function (list) {
  1169. var L = list.length;
  1170. var i = Math.ceil(Math.random() * L);
  1171.  
  1172. return list[i];
  1173. },
  1174. random: function (min, max) {
  1175.  
  1176. return Math.floor(Math.random() * (max - min)) + min;
  1177. },
  1178.  
  1179. Sleep: function (ms) {
  1180. return new Promise(resolve => setTimeout(() => resolve('sleep'), ms));
  1181. }
  1182.  
  1183. }
  1184.  
  1185. let errorMsg = {
  1186. "-1": "应用程序不存在或已被封禁!",
  1187. "-2": "Access Key错误!",
  1188. "-3": "API校验密匙错误!",
  1189. "-4": "调用方对该Method没有权限!",
  1190. "-101": "账号未登录!",
  1191. "-102": "账号被封停!",
  1192. "-103": "积分不足!",
  1193. "-104": "硬币不足!",
  1194. "-105": "验证码错误!",
  1195. "-106": "账号非正式会员或在适应期!",
  1196. "-107": "应用不存在或者被封禁!",
  1197. "-108": "未绑定手机!",
  1198. "-109": "未知!",
  1199. "-110": "未绑定手机!",
  1200. "-111": "csrf 校验失败!",
  1201. "-112": "系统升级中!",
  1202. "-113": "账号尚未实名认证!",
  1203. "-114": "请先绑定手机!",
  1204. "-115": "请先完成实名认证!",
  1205. "-304": "木有改动!",
  1206. "-307": "撞车跳转!",
  1207. "-400": "请求错误!",
  1208. "-401": "未认证!",
  1209. "-403": "访问权限不足!",
  1210. "-404": "啥都木有!",
  1211. }
  1212.  
  1213. /*-----------------------------------------------CODE 统一检查--------------------------------------------------*/
  1214. /**
  1215. *
  1216. * @param code
  1217. * @constructor
  1218. */
  1219. let chackCode = function (code) {
  1220.  
  1221. let emsg = errorMsg[code + ""];
  1222. if (emsg != null) {
  1223. javaex.tip({content: emsg, type: "error"});
  1224.  
  1225. return false;
  1226. }
  1227.  
  1228. return true;
  1229. }
  1230.  
  1231.  
  1232. /*-----------------------------------------------localStorage封装 (本地存储信息)--------------------------------------------------*/
  1233. //javaex.setLocalStorage(key, value); var str = javaex.getLocalStorage(key); javaex.deleteLocalStorage(key);
  1234.  
  1235. /*window.onbeforeunload = function() {
  1236. if (!canLeavePage()) {
  1237. return ('确认离开当前页面吗?未保存的数据将会丢失!');
  1238. }
  1239. };*/
  1240.  
  1241.  
  1242. /**
  1243. * Ajax请求对象
  1244. */
  1245. const Ajax = (() => {
  1246. /**
  1247. * 检查options是否符合要求
  1248. * @param {object} options
  1249. * @returns {boolean}
  1250. */
  1251. function checkOptions(options) {
  1252. let result = false;
  1253. if (typeof options !== 'object') {
  1254. console.warn('类型错误: typeof Options !== Object');
  1255. return result;
  1256. } else {
  1257. if (typeof options.url !== 'string') {
  1258. console.warn('类型错误: typeof Link !== Strings');
  1259. return result;
  1260. } else {
  1261. const reg = /^https?:\/\/(?:\w+\.?)+(?:\/.*)*\/?$/i;
  1262. if (!reg.test(options.url)) {
  1263. console.warn('url字符串须为完整http链接');
  1264. return result;
  1265. }
  1266. result = true;
  1267. }
  1268. }
  1269. return result;
  1270. }
  1271.  
  1272. /**
  1273. * 对象转URL编码
  1274. * @param {object} data
  1275. */
  1276. function objToURLCode(data) {
  1277. var _result = [];
  1278. for (var key in data) {
  1279. var value = data[key];
  1280. if (value instanceof Array) {
  1281. value.forEach(function (_value) {
  1282. _result.push(key + "=" + _value);
  1283. });
  1284. } else {
  1285. _result.push(key + '=' + value);
  1286. }
  1287. }
  1288. return _result.join('&');
  1289. }
  1290.  
  1291. /**
  1292. * 请求
  1293. * @param {string} method
  1294. * @param {object} options
  1295. */
  1296. function request(method, options) {
  1297. if (checkOptions(options)) {
  1298. let xhr = new XMLHttpRequest();
  1299. const {url: _url, queryStringsObj, data, dataType, hasCookies} = options
  1300. , url = typeof queryStringsObj === 'object' ?
  1301. _url + '?' + objToURLCode(queryStringsObj) : _url;
  1302. switch (method) {
  1303. case 'GET':
  1304. xhr.open("GET", url);
  1305. break;
  1306. case 'POST':
  1307. xhr.open("POST", url);
  1308. xhr.setRequestHeader('Content-Type', dataType);
  1309. break;
  1310. default:
  1311. break;
  1312. }
  1313. if (hasCookies) xhr.withCredentials = true;
  1314. xhr.timeout = 3000;
  1315. xhr.addEventListener('load', () => {
  1316. if (xhr.status === 200) {
  1317. options.success(xhr.responseText)
  1318. } else {
  1319. console.error(`status:${xhr.status}`);
  1320. options.success(`{"code":${xhr.status},"msg":"频繁访问"}`);
  1321. }
  1322. })
  1323. xhr.addEventListener('error', () => {
  1324. console.error('ajax请求出错')
  1325. options.success('{"code":-1,"msg":"ajax请求出错"}');
  1326. })
  1327. xhr.addEventListener('timeout', () => {
  1328. console.error('请求超时')
  1329. options.success('{"code":-1,"msg":"请求超时"}');
  1330. })
  1331. switch (method) {
  1332. case 'GET':
  1333. xhr.send()
  1334. break;
  1335. case 'POST':
  1336. xhr.send((/urlencoded/.test(dataType)) ? objToURLCode(data) : data)
  1337. break;
  1338. default:
  1339. break;
  1340. }
  1341. }
  1342. }
  1343.  
  1344. return {
  1345. /**
  1346. * 发送Get请求
  1347. * @param {Object} options
  1348. */
  1349. get(options) {
  1350. request("GET", options);
  1351. },
  1352. /**
  1353. * 发送Post请求
  1354. * @param {object} options
  1355. */
  1356. post(options) {
  1357. request("POST", options);
  1358. }
  1359. }
  1360. })()