b-live-random-send-test

定时从设置的字幕中随机取出一条在B站直播间发送,需先登录(不可用)B站账号

当前为 2023-05-01 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/447936/1184085/b-live-random-send-test.js

  1. // ==UserScript==
  2. // @author Gamyou
  3. // @version 1.5.4
  4. // @note 23-05-01 1.5.4 自动参加抽奖
  5. // ==/UserScript==
  6.  
  7.  
  8. (function () {
  9. const blobURL = URL.createObjectURL(
  10. new Blob(
  11. [
  12. '(',
  13. function () {
  14. const ids = {};
  15. // 监听message 开始执行定时器或者销毁
  16. self.onmessage = (e) => {
  17. switch (e.data.command) {
  18. case 'interval:start': // 开启定时器
  19. const intervalId = setInterval(() => postMessage({ message: 'interval:tick', id: e.data.id }), e.data.interval);
  20. // postMessage({ message: 'interval:started', id: e.data.id });
  21. ids[e.data.id] = intervalId;
  22. break;
  23. case 'interval:clear': // 销毁
  24. clearInterval(ids[e.data.id]);
  25. postMessage({ message: 'interval:cleared', id: e.data.id });
  26. delete ids[e.data.id];
  27. break;
  28. case 'timeout:start':
  29. const timeoutId = setTimeout(() => postMessage({ message: 'timeout:tick', id: e.data.id }), e.data.timeout);
  30. // postMessage({ message: 'timeout:started', id: e.data.id });
  31. ids[e.data.id] = timeoutId;
  32. break;
  33. case 'timeout:clear':
  34. clearTimeout(ids[e.data.id]);
  35. postMessage({ message: 'timeout:cleared', id: e.data.id });
  36. delete ids[e.data.id];
  37. break;
  38. }
  39. };
  40. }.toString(),
  41. ')()',
  42. ],
  43. { type: 'application/javascript' },
  44. ),
  45. );
  46. const worker = new Worker(blobURL);
  47. URL.revokeObjectURL(blobURL); //用完释放URL对象
  48. const workerTimer = {
  49. id: 0,
  50. callbacks: {},
  51. setInterval: (cb, interval, context) => {
  52. const id = ++workerTimer.id;
  53. workerTimer.callbacks[id] = { fn: cb, context: context };
  54. worker.postMessage({ command: 'interval:start', interval: interval, id: id });
  55. return id;
  56. },
  57. setTimeout: (cb, timeout, context) => {
  58. const id = ++workerTimer.id;
  59. workerTimer.callbacks[id] = { fn: cb, context: context };
  60. worker.postMessage({ command: 'timeout:start', timeout: timeout, id: id });
  61. return id;
  62. },
  63.  
  64. // 监听worker 里面的定时器发送的message 然后执行回调函数
  65. onMessage: (e) => {
  66. switch (e.data.message) {
  67. case 'interval:tick':
  68. case 'timeout:tick':
  69. const callbackItem = workerTimer.callbacks[e.data.id];
  70. if (callbackItem && callbackItem.fn)
  71. callbackItem.fn.apply(callbackItem.context);
  72.  
  73. break;
  74. case 'interval:cleared':
  75. case 'timeout:cleared':
  76. delete workerTimer.callbacks[e.data.id];
  77. break;
  78. }
  79. },
  80.  
  81. // 往worker里面发送销毁指令
  82. clearInterval: (id) => worker.postMessage({ command: 'interval:clear', id: id }),
  83. clearTimeout: (id) => worker.postMessage({ command: 'timeout:clear', id: id }),
  84. };
  85. worker.onmessage = workerTimer.onMessage.bind(workerTimer);
  86.  
  87. let source = {
  88. version: 3,
  89. random: true,
  90. data1: { available: true, values: ['弹幕①', '弹幕②'] },
  91. data2: { available: true, values: ['弹幕③', '弹幕④'] },
  92. data3: { available: true, values: ['弹幕⑤', '弹幕⑥'] },
  93. data4: { available: true, values: ['弹幕⑦', '弹幕⑧'] },
  94. data5: { available: true, values: ['弹幕⑨', '弹幕Ⅹ'] }
  95. },
  96. rdCheckbox, group1Checkbox, group2Checkbox, group3Checkbox, group4Checkbox, group5Checkbox,
  97. dmButtonSend, dmInput, divSetting, dataText1, dataText2, dataText3, dataText4, dataText5, spanApplyTip,
  98. pdata = {}, waiters = [], data = [],
  99. sendTimer = null, removeElementsTimer = null, signInTimer = null, miniCloseTimer = null,
  100. count = 0, waitCount = 200, arrayIndex = 0, removeElementsTimerCount = 0, default_timeout = 600,
  101. // hbInterval = Math.floor(Math.random() * (35 - 50)) + 50,
  102. gmNotice = obj => { alert('请更新油猴脚本'); window.location.href = parentUrl; },
  103. getGmValue = (key, defaultValue) => { return null; },
  104. setGmValue = (key, obj) => { console.warn('===> No implementation "setGmValue" method.'); },
  105. delGmValue = key => { console.warn('===> No implementation "delGmValue" method.'); };
  106.  
  107. const minVersion = '2.4.0', updateTips = '添加B站直播间防休眠功能', noticeTimeout = 10e3,
  108. icoUrl = 'https://www.bilibili.com/favicon.ico',
  109. parentUrl = 'https://gf.qytechs.cn/scripts/446725-b%E7%AB%99%E7%9B%B4%E6%92%AD%E9%97%B4%E5%AE%9A%E6%97%B6%E5%8F%91%E9%9A%8F%E6%9C%BA%E5%BC%B9%E5%B9%95/code/B%E7%AB%99%E7%9B%B4%E6%92%AD%E9%97%B4%E5%AE%9A%E6%97%B6%E5%8F%91%E9%9A%8F%E6%9C%BA%E5%BC%B9%E5%B9%95.user.js',
  110. // roomId = window.__NEPTUNE_IS_MY_WAIFU__
  111. // ? 0 == window.__NEPTUNE_IS_MY_WAIFU__.roomInitRes.data.short_id
  112. // ? window.__NEPTUNE_IS_MY_WAIFU__.roomInitRes.data.room_id
  113. // : window.__NEPTUNE_IS_MY_WAIFU__.roomInitRes.data.short_id
  114. // : window.location.pathname.replace(/^\/(\S+\/)*/g, ''),
  115. roomId = window.location.pathname.replace(/^\/(\S+\/)*/g, ''),
  116. setGmGetValue = callback => getGmValue = callback,
  117. setGmSetValue = callback => setGmValue = callback,
  118. setGmDelValue = callback => delGmValue = callback,
  119. setGmNotice = callback => gmNotice = callback,
  120. setParentData = obj => pdata = obj,
  121. arrayInfo = () => console.info(data),
  122. // setLoadedFlag = flag => window.autoSendDanmuModuleLoaded = flag,
  123. isOldVersion = () => {
  124. if (!pdata.version) {
  125. return true;
  126. }
  127. if (minVersion === pdata.version) {
  128. return false;
  129. } else {
  130. let vals = pdata.version.split('.');
  131. let mins = minVersion.split('.');
  132. if (vals.length != mins.length) {
  133. return true;
  134. } else {
  135. for (let i = 0; i < vals.length; i++) {
  136. if (mins[i] > vals[i]) {
  137. return true;
  138. }
  139. }
  140.  
  141. return false;
  142. }
  143. }
  144. },
  145. initCss = () => {
  146. let linkElement = document.createElement('link');
  147. linkElement.rel = 'stylesheet';
  148. linkElement.href = 'https://unpkg.com/element-ui@2.15.9/lib/theme-chalk/index.css';
  149. document.head.appendChild(linkElement);
  150.  
  151. // 图标库 https://ionic.io/ionicons
  152. // let scriptElement = document.createElement('script');
  153. // scriptElement.src = 'https://unpkg.com/ionicons@5.5.2/dist/ionicons.js';
  154. // document.head.appendChild(scriptElement);
  155.  
  156. let customerStyle = document.createElement('style');
  157. customerStyle.setAttribute('type', 'text/css');
  158. customerStyle.innerHTML = '.danmu-group-title{font-size:14px;padding-left:2px;color:rgb(18, 56, 141);display:inline;margin-right:60%;vertical-align:middle;}.danmu-group-textarea{width:98%;min-height:100px;height:16%;margin:1px 0px 4px;border:0px;resize:none;}.el-button{display:inline-block;line-height:1;white-space:nowrap;cursor:pointer;background:#FFF;border:1px solid #DCDFE6;color:#606266;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;-webkit-transition:.1s;transition:.1s;font-weight:500;padding:12px 20px;font-size:14px;border-radius:4px}.el-button.is-circle{border-radius:50%;padding:12px}.el-button--mini.is-circle{padding:3px;}.el-button:focus,.el-button:hover{color:#409EFF;border-color:#c6e2ff;background-color:#ecf5ff}.el-icon-close.is-circle{padding:5px;color:#ff0000;border:1px solid #ff0000;margin-left:20px;}.el-icon-check.is-circle{padding:5px;color:#0000ff;border:1px solid #0000ff;margin-left:20px;}input[type="checkbox"]{display:none;}.switch-check{display:inline-block;margin:0 5px;vertical-align:middle;}.switch-check-label{display:inline-block;vertical-align:middle;border:1px solid #bdc3c7;border-radius:60px;width:40px;height:18px;position:relative;transition:all .3s;cursor:pointer;}.switch-check-label:before{width:14px;height:14px;content:"";display:inline-block;background-color:#bdc3c7;border-radius:100%;position:absolute;top:2px;left:4px;transition:all .3s;}.switch-check :checked ~ label{background-color:#26b22b;border-color:#26b22b;}.switch-check :checked ~ label:before{left:22px;background-color:#fff;}.danmu-random-setting-panel{background-color:#d4f2e0;border-radius:2px;width:100%;height:100%;overflow-y:auto;position:absolute;left:0px;top:0px;z-index:999;display:none;}.danmu-random-setting-title{text-align:center;font-size:16px;font-weight:700;color:#1c5adc;line-height:30px;}.danmu-random-setting-tips{color:#0b81cc;text-align:center;font-style:italic;}.danmu-random-update-tips{color:#0b81cc;text-align:center;font-size:13px;font-weight:700;margin:10px 0px;}.danmu-random-setting-bottom{width:100%;line-height:35px;}.danmu-random-switch-button-title{font-size:16px;vertical-align:middle;margin-right:4px;color:#095ca2;cursor:help;}.danmu-random-setting-success-tips{text-align:center;display:inline-block;vertical-align:middle;width:34%;}.danmu-random-setting-success-text{font-size:16px;color:#128712;display:none;}.danmu-random-set-button-container{display:inline-block;vertical-align:middle;}';
  159. document.head.appendChild(customerStyle);
  160. },
  161. // initScript = () => {
  162. // let script = document.createElement('script');
  163. // script.type = 'text/javascript';
  164. // script.src = 'https://cdn.jsdelivr.net/npm/crypto-js@4.1.1/crypto-js.js';
  165. // document.head.appendChild(script);
  166. // },
  167. getCurrentTimestamp = () => new Date().getTime(),
  168. send = (msg, index) => {
  169. let dmTextArea = document.getElementById('aside-area-vm').getElementsByClassName('chat-input border-box')[0];
  170. if (!dmTextArea) {
  171. alert('找不到输入弹幕文本框,请尝试刷新页面');
  172. return;
  173. }
  174.  
  175. let btnSend = document.getElementsByClassName('bl-button live-skin-highlight-button-bg live-skin-button-text bl-button--primary bl-button--small')[0];
  176. if (!btnSend) {
  177. alert('找不到发送按钮,请尝试刷新页面');
  178. return;
  179. }
  180. // if (getCurrentTimestamp() - lastSent < 5e3) {
  181. // setTimeout(() => send(msg, index), 5e3);
  182. // console.log('===> 发送间隔少于5秒,进入递归处理');
  183. // } else {
  184. dmTextArea.value = msg;
  185. // 定义事件, 定义才可发送
  186. dmTextArea.dispatchEvent(new Event('input', { "bubbles": true, "cancelable": true }));
  187. btnSend.click();
  188. lastSent = getCurrentTimestamp();
  189. ++count;
  190. console.log('===> ' + new Date().toLocaleString() + ' 弹幕发送成功 ' + count + ' 次,第【' + index + '】条数据 === ' + msg);
  191. // }
  192. },
  193. isNull = str => {
  194. if (!str || str == "")
  195. return true;
  196.  
  197. let regu = "^[ ]+$";
  198. let re = new RegExp(regu);
  199. return re.test(str);
  200. },
  201. randomSort = arr => {
  202. for (let i = 0; i < arr.length; i++) {
  203. const rdIndex = Math.floor(Math.random() * arr.length);
  204. const temp = arr[i];
  205. arr[i] = arr[rdIndex];
  206. arr[rdIndex] = temp;
  207. }
  208.  
  209. return arr;
  210. },
  211. clearWaiters = () => {
  212. for (let i = 0; i < waiters.length; i++) {
  213. workerTimer.clearInterval(waiters[i]);
  214. waiters[i] = null;
  215. }
  216.  
  217. waiters = [];
  218. },
  219. signIn = () => {
  220. if (!signInTimer) {
  221. let timestamp = new Date(new Date(new Date().setDate(new Date().getDate() + 1)).toDateString()).getTime() - getCurrentTimestamp();
  222. console.log('===> 设置凌晨打卡定时器【' + timestamp + '】');
  223. signInTimer = workerTimer.setTimeout(() => {
  224. // if (dmButtonSend.textContent === '停止')
  225. send(pdata.signText ? pdata.signText : '打卡', 0);
  226. console.log('===> 进入下一轮递归打卡');
  227. workerTimer.clearTimeout(signInTimer);
  228. signInTimer = null;
  229. signIn();
  230. }, timestamp);
  231. }
  232. },
  233. // selectRandom = () => source.random = rdCheckbox.checked,
  234. setCheckboxChecked = () => {
  235. rdCheckbox.checked = source.random;
  236. group1Checkbox.checked = source.data1.available;
  237. group2Checkbox.checked = source.data2.available;
  238. group3Checkbox.checked = source.data3.available;
  239. group4Checkbox.checked = source.data4.available;
  240. group5Checkbox.checked = source.data5.available;
  241. },
  242. openSetting = () => divSetting.style.display = 'block',
  243. closeSetting = () => {
  244. setCheckboxChecked();
  245. divSetting.style.display = 'none';
  246. },
  247. initData = () => {
  248. if (source.data1.values.length <= 0
  249. && source.data2.values.length <= 0
  250. && source.data3.values.length <= 0
  251. && source.data4.values.length <= 0
  252. && source.data5.values.length <= 0) {
  253. return data ? data : [];
  254. }
  255.  
  256. let result = [];
  257. result = source.data1.available ? result.concat(source.data1.values) : result;
  258. result = source.data2.available ? result.concat(source.data2.values) : result;
  259. result = source.data3.available ? result.concat(source.data3.values) : result;
  260. result = source.data4.available ? result.concat(source.data4.values) : result;
  261. result = source.data5.available ? result.concat(source.data5.values) : result;
  262. data = result;
  263. source.random ? data = randomSort(result) : arrayIndex = 0;
  264. },
  265. applySetting = () => {
  266. source.data1.values = isNull(dataText1.value) ? [] : dataText1.value.split('|');
  267. source.data2.values = isNull(dataText2.value) ? [] : dataText2.value.split('|');
  268. source.data3.values = isNull(dataText3.value) ? [] : dataText3.value.split('|');
  269. source.data4.values = isNull(dataText4.value) ? [] : dataText4.value.split('|');
  270. source.data5.values = isNull(dataText5.value) ? [] : dataText5.value.split('|');
  271. source.random = rdCheckbox.checked;
  272. source.data1.available = group1Checkbox.checked;
  273. source.data2.available = group2Checkbox.checked;
  274. source.data3.available = group3Checkbox.checked;
  275. source.data4.available = group4Checkbox.checked;
  276. source.data5.available = group5Checkbox.checked;
  277. initData();
  278. setGmValue(roomId, source);
  279. spanApplyTip.style.display = 'block';
  280. setTimeout(() => {
  281. spanApplyTip.style.display = 'none';
  282. divSetting.style.display = 'none';
  283. }, 1500);
  284. },
  285. danmu = () => {
  286. if (data.length < 1) {
  287. gmNotice({
  288. text: '请任意在一个分组里输入一条弹幕',
  289. title: '没有弹幕数据,请先设置',
  290. image: icoUrl,
  291. highlight: true,
  292. timeout: noticeTimeout
  293. });
  294. return false;
  295. }
  296. if (source.random)
  297. arrayIndex = Math.floor((Math.random() * data.length));
  298.  
  299. send(data[arrayIndex], arrayIndex);
  300. ++arrayIndex;
  301. if (arrayIndex >= data.length)
  302. arrayIndex = 0;
  303.  
  304. return true;
  305. },
  306. offOrOn = () => {
  307. let timeout = 0;
  308. if (sendTimer) {
  309. workerTimer.clearInterval(sendTimer);
  310. sendTimer = null;
  311. dmButtonSend.style.background = 'rgba(217,157,27,1)';
  312. dmButtonSend.textContent = '开始';
  313. dmInput.removeAttribute("disabled");
  314. } else {
  315. timeout = isNull(dmInput.value) ? default_timeout * 1e3 : dmInput.value * 1e3;
  316. if (!danmu())
  317. return;
  318.  
  319. sendTimer = workerTimer.setInterval(danmu, timeout);
  320. dmButtonSend.style.background = '#ff0000';
  321. dmButtonSend.textContent = '停止';
  322. dmInput.setAttribute('disabled', 'disabled');
  323. }
  324. },
  325. buildPanel = divButton => {
  326. /* ----------------------------------------- head ----------------------------------------- */
  327. let divSettingTitle = document.createElement('div');
  328. divSettingTitle.textContent = '弹幕设置';
  329. divSettingTitle.classList.add('danmu-random-setting-title');
  330.  
  331. let divTip = document.createElement('div');
  332. divTip.classList.add('danmu-random-setting-tips');
  333. divTip.innerHTML = '任一分组内输入弹幕即可,多条用<span style="color:#dc6b07;margin:0 2px 0 4px;font-weight:700;font-style:normal;">竖线</span>分隔';
  334.  
  335. let divUpdateTip = document.createElement('div');
  336. divUpdateTip.classList.add('danmu-random-update-tips');
  337. divUpdateTip.innerHTML = `<span style="color:#f00">更新提示:</span>${updateTips}`;
  338. /* ----------------------------------------- head ----------------------------------------- */
  339.  
  340. /* ----------------------------------------- textarea 1 ----------------------------------------- */
  341. let divText1 = document.createElement('div');
  342. divText1.textContent = '分组 1 :';
  343. divText1.classList.add('danmu-group-title');
  344.  
  345. group1Checkbox = document.createElement('input');
  346. group1Checkbox.type = 'checkbox';
  347. group1Checkbox.id = 'group1Checkbox';
  348. group1Checkbox.checked = true;
  349.  
  350. let lblGroup1Checkbox = document.createElement('label');
  351. lblGroup1Checkbox.setAttribute('for', 'group1Checkbox');
  352. lblGroup1Checkbox.classList.add('switch-check-label');
  353.  
  354. let divGroup1Checkbox = document.createElement('div');
  355. divGroup1Checkbox.classList.add('switch-check');
  356. divGroup1Checkbox.appendChild(group1Checkbox);
  357. divGroup1Checkbox.appendChild(lblGroup1Checkbox);
  358.  
  359. dataText1 = document.createElement('textarea');
  360. dataText1.classList.add('danmu-group-textarea');
  361. dataText1.setAttribute('placeholder', '请输入弹幕,多条弹幕请用“|”分隔');
  362. /* ----------------------------------------- textarea 1 ----------------------------------------- */
  363.  
  364. /* ----------------------------------------- textarea 2 ----------------------------------------- */
  365. let divText2 = document.createElement('div');
  366. divText2.textContent = '分组 2 :';
  367. divText2.classList.add('danmu-group-title');
  368.  
  369. group2Checkbox = document.createElement('input');
  370. group2Checkbox.type = 'checkbox';
  371. group2Checkbox.id = 'group2Checkbox';
  372. group2Checkbox.checked = true;
  373.  
  374. let lblGroup2Checkbox = document.createElement('label');
  375. lblGroup2Checkbox.setAttribute('for', 'group2Checkbox');
  376. lblGroup2Checkbox.classList.add('switch-check-label');
  377.  
  378. let divGroup2Checkbox = document.createElement('div');
  379. divGroup2Checkbox.classList.add('switch-check');
  380. divGroup2Checkbox.appendChild(group2Checkbox);
  381. divGroup2Checkbox.appendChild(lblGroup2Checkbox);
  382.  
  383. dataText2 = document.createElement('textarea');
  384. dataText2.classList.add('danmu-group-textarea');
  385. dataText2.setAttribute('placeholder', '请输入弹幕,多条弹幕请用“|”分隔');
  386. /* ----------------------------------------- textarea 2 ----------------------------------------- */
  387.  
  388. /* ----------------------------------------- textarea 3 ----------------------------------------- */
  389. let divText3 = document.createElement('div');
  390. divText3.textContent = '分组 3 :';
  391. divText3.classList.add('danmu-group-title');
  392.  
  393. group3Checkbox = document.createElement('input');
  394. group3Checkbox.type = 'checkbox';
  395. group3Checkbox.id = 'group3Checkbox';
  396. group3Checkbox.checked = true;
  397.  
  398. let lblGroup3Checkbox = document.createElement('label');
  399. lblGroup3Checkbox.setAttribute('for', 'group3Checkbox');
  400. lblGroup3Checkbox.classList.add('switch-check-label');
  401.  
  402. let divGroup3Checkbox = document.createElement('div');
  403. divGroup3Checkbox.classList.add('switch-check');
  404. divGroup3Checkbox.appendChild(group3Checkbox);
  405. divGroup3Checkbox.appendChild(lblGroup3Checkbox);
  406.  
  407. dataText3 = document.createElement('textarea');
  408. dataText3.classList.add('danmu-group-textarea');
  409. dataText3.setAttribute('placeholder', '请输入弹幕,多条弹幕请用“|”分隔');
  410. /* ----------------------------------------- textarea 3 ----------------------------------------- */
  411.  
  412. /* ----------------------------------------- textarea 4 ----------------------------------------- */
  413. let divText4 = document.createElement('div');
  414. divText4.textContent = '分组 4 :';
  415. divText4.classList.add('danmu-group-title');
  416.  
  417. group4Checkbox = document.createElement('input');
  418. group4Checkbox.type = 'checkbox';
  419. group4Checkbox.id = 'group4Checkbox';
  420. group4Checkbox.checked = true;
  421.  
  422. let lblGroup4Checkbox = document.createElement('label');
  423. lblGroup4Checkbox.setAttribute('for', 'group4Checkbox');
  424. lblGroup4Checkbox.classList.add('switch-check-label');
  425.  
  426. let divGroup4Checkbox = document.createElement('div');
  427. divGroup4Checkbox.classList.add('switch-check');
  428. divGroup4Checkbox.appendChild(group4Checkbox);
  429. divGroup4Checkbox.appendChild(lblGroup4Checkbox);
  430.  
  431. dataText4 = document.createElement('textarea');
  432. dataText4.classList.add('danmu-group-textarea');
  433. dataText4.setAttribute('placeholder', '请输入弹幕,多条弹幕请用“|”分隔');
  434. /* ----------------------------------------- textarea 4 ----------------------------------------- */
  435.  
  436. /* ----------------------------------------- textarea 5 ----------------------------------------- */
  437. let divText5 = document.createElement('div');
  438. divText5.textContent = '分组 5 :';
  439. divText5.classList.add('danmu-group-title');
  440.  
  441. group5Checkbox = document.createElement('input');
  442. group5Checkbox.type = 'checkbox';
  443. group5Checkbox.id = 'group5Checkbox';
  444. group5Checkbox.checked = true;
  445.  
  446. let lblGroup5Checkbox = document.createElement('label');
  447. lblGroup5Checkbox.setAttribute('for', 'group5Checkbox');
  448. lblGroup5Checkbox.classList.add('switch-check-label');
  449.  
  450. let divGroup5Checkbox = document.createElement('div');
  451. divGroup5Checkbox.classList.add('switch-check');
  452. divGroup5Checkbox.appendChild(group5Checkbox);
  453. divGroup5Checkbox.appendChild(lblGroup5Checkbox);
  454.  
  455. dataText5 = document.createElement('textarea');
  456. dataText5.classList.add('danmu-group-textarea');
  457. dataText5.setAttribute('placeholder', '请输入弹幕,多条弹幕请用“|”分隔');
  458. /* ----------------------------------------- textarea 5 ----------------------------------------- */
  459.  
  460. /* ----------------------------------------- random chackbox ----------------------------------------- */
  461. let descCheckbox = document.createElement('span');
  462. descCheckbox.textContent = '随机';
  463. descCheckbox.title = '将合并所有分组数据,从中随机选出一条发送';
  464. descCheckbox.classList.add('danmu-random-switch-button-title');
  465.  
  466. rdCheckbox = document.createElement('input');
  467. rdCheckbox.type = 'checkbox';
  468. rdCheckbox.id = 'rdmCheckbox';
  469. rdCheckbox.checked = true;
  470. // rdCheckbox.addEventListener('click', selectRandom);
  471.  
  472. let lblCheckbox = document.createElement('label');
  473. lblCheckbox.setAttribute('for', 'rdmCheckbox');
  474. lblCheckbox.classList.add('switch-check-label');
  475.  
  476. let divCheckbox = document.createElement('div');
  477. divCheckbox.classList.add('switch-check');
  478. divCheckbox.style.marginLeft = '10px';
  479. divCheckbox.appendChild(descCheckbox);
  480. divCheckbox.appendChild(rdCheckbox);
  481. divCheckbox.appendChild(lblCheckbox);
  482. /* ----------------------------------------- random chackbox ----------------------------------------- */
  483.  
  484. /* ----------------------------------------- div tip ----------------------------------------- */
  485. spanApplyTip = document.createElement('span');
  486. spanApplyTip.textContent = '设置成功';
  487. spanApplyTip.classList.add('danmu-random-setting-success-text');
  488.  
  489. let divApplyTip = document.createElement('div');
  490. divApplyTip.classList.add('danmu-random-setting-success-tips');
  491. divApplyTip.appendChild(spanApplyTip);
  492. /* ----------------------------------------- div tip ----------------------------------------- */
  493.  
  494. /* ----------------------------------------- appley and close button ----------------------------------------- */
  495. let btnApplySetting = document.createElement('i');
  496. btnApplySetting.setAttribute('title', '应用');
  497. btnApplySetting.classList.add('el-button');
  498. btnApplySetting.classList.add('el-icon-check');
  499. btnApplySetting.classList.add('is-circle');
  500. btnApplySetting.addEventListener('click', applySetting);
  501.  
  502. let btnCloseSetting = document.createElement('i');
  503. btnCloseSetting.setAttribute('title', '关闭');
  504. btnCloseSetting.classList.add('el-button');
  505. btnCloseSetting.classList.add('el-icon-close');
  506. btnCloseSetting.classList.add('is-circle');
  507. btnCloseSetting.addEventListener('click', closeSetting);
  508.  
  509. let divSettingButton = document.createElement('div');
  510. divSettingButton.classList.add('danmu-random-set-button-container');
  511. divSettingButton.appendChild(btnApplySetting);
  512. divSettingButton.appendChild(btnCloseSetting);
  513. /* ----------------------------------------- appley and close button ----------------------------------------- */
  514.  
  515. /* ----------------------------------------- container ----------------------------------------- */
  516. let divBottomContainer = document.createElement('div');
  517. divBottomContainer.classList.add('danmu-random-setting-bottom');
  518. divBottomContainer.appendChild(divCheckbox);
  519. divBottomContainer.appendChild(divApplyTip);
  520. divBottomContainer.appendChild(divSettingButton);
  521.  
  522. let divContainer = document.createElement('div');
  523. divContainer.style.height = 'calc(98% - 30px - 25px)';
  524. divContainer.appendChild(divText1);
  525. divContainer.appendChild(divGroup1Checkbox);
  526. divContainer.appendChild(dataText1);
  527. divContainer.appendChild(divText2);
  528. divContainer.appendChild(divGroup2Checkbox);
  529. divContainer.appendChild(dataText2);
  530. divContainer.appendChild(divText3);
  531. divContainer.appendChild(divGroup3Checkbox);
  532. divContainer.appendChild(dataText3);
  533. divContainer.appendChild(divText4);
  534. divContainer.appendChild(divGroup4Checkbox);
  535. divContainer.appendChild(dataText4);
  536. divContainer.appendChild(divText5);
  537. divContainer.appendChild(divGroup5Checkbox);
  538. divContainer.appendChild(dataText5);
  539. divContainer.appendChild(divBottomContainer);
  540. /* ----------------------------------------- container ----------------------------------------- */
  541.  
  542. divSetting = document.createElement('div');
  543. divSetting.id = 'danmu-setting-panel';
  544. divSetting.classList.add('danmu-random-setting-panel');
  545. divSetting.appendChild(divSettingTitle);
  546. divSetting.appendChild(divTip);
  547. divSetting.appendChild(divUpdateTip);
  548. divSetting.appendChild(divContainer);
  549.  
  550. let asideAreaVm = document.getElementById('aside-area-vm');
  551. asideAreaVm.appendChild(divSetting);
  552.  
  553. /* ----------------------------------------- function ----------------------------------------- */
  554. dmButtonSend = document.createElement('button');
  555. dmButtonSend.textContent = '开始';
  556. dmButtonSend.style.minWidth = '65px';
  557. dmButtonSend.style.height = '24px';
  558. dmButtonSend.style.fontSize = '12px';
  559. dmButtonSend.style.borderRadius = '4px';
  560. dmButtonSend.style.color = '#ffffff';
  561. dmButtonSend.style.background = 'rgba(217,157,27,1)';
  562. dmButtonSend.style.border = '0';
  563. dmButtonSend.style.cursor = 'pointer';
  564. //dmButtonSend.onclick = function() { alert('Hello world');}
  565. dmButtonSend.addEventListener('click', offOrOn);
  566.  
  567. let beforeSpan = document.createElement('span');
  568. beforeSpan.textContent = '每';
  569. beforeSpan.style.color = '#ffffff';
  570. beforeSpan.style.fontSize = '12px';
  571. beforeSpan.style.marginLeft = '4px';
  572. beforeSpan.style.backgroundColor = '#ec6c1b';
  573.  
  574. dmInput = document.createElement('input');
  575. dmInput.value = default_timeout;
  576. dmInput.style.width = '25px';
  577. dmInput.style.height = '15px';
  578. dmInput.style.margin = '0 3px';
  579. dmInput.style.border = '0';
  580. dmInput.style.borderRadius = '3px';
  581. dmInput.setAttribute('oninput', "this.value = this.value.replace(/[^0-9]/g, '')");
  582.  
  583. let afterSpan = document.createElement('span');
  584. afterSpan.textContent = '秒发送';
  585. afterSpan.style.color = '#ffffff';
  586. afterSpan.style.fontSize = '12px';
  587. afterSpan.style.backgroundColor = '#ec6c1b';
  588. afterSpan.style.marginRight = '4px';
  589.  
  590. let iElement = document.createElement('i');
  591. iElement.classList.add('el-icon-setting');
  592.  
  593. let btnSetting = document.createElement('button');
  594. btnSetting.title = '设置';
  595. btnSetting.classList.add('el-button');
  596. btnSetting.classList.add('el-button--mini');
  597. btnSetting.classList.add('is-circle');
  598. btnSetting.addEventListener('click', openSetting);
  599. btnSetting.appendChild(iElement);
  600.  
  601. // let btnSetting = document.createElement('ion-icon');
  602. // btnSetting.setAttribute('name', 'settings-sharp');
  603. // btnSetting.classList.add('el-button');
  604. // btnSetting.classList.add('el-button--mini');
  605. // btnSetting.classList.add('is-circle');
  606. // btnSetting.addEventListener('click', openSetting);
  607.  
  608. let div = document.createElement('div');
  609. div.style.position = 'absolute';
  610. div.appendChild(dmButtonSend);
  611. div.appendChild(beforeSpan);
  612. div.appendChild(dmInput);
  613. div.appendChild(afterSpan);
  614. div.appendChild(btnSetting);
  615. divButton.appendChild(div);
  616. /* ----------------------------------------- function ----------------------------------------- */
  617. },
  618. removeElements = () => {
  619. let switchLoginGuideVm = document.getElementById('switch-login-guide-vm');
  620. if (switchLoginGuideVm)
  621. switchLoginGuideVm.style.setProperty('display', 'none', 'important');
  622.  
  623. let myDearHarunaVm = document.getElementById('my-dear-haruna-vm');
  624. if (myDearHarunaVm)
  625. myDearHarunaVm.style.setProperty('display', 'none', 'important');
  626.  
  627. let shopPopoverVm = document.getElementById('shop-popover-vm');
  628. if (shopPopoverVm)
  629. shopPopoverVm.style.setProperty('display', 'none', 'important');
  630.  
  631. if (removeElementsTimer) {
  632. workerTimer.clearInterval(removeElementsTimer);
  633. removeElementsTimer = null;
  634. }
  635. removeElementsTimer = workerTimer.setInterval(() => {
  636. ++removeElementsTimerCount;
  637. let ltRow = document.getElementsByClassName('lt-row')[0];
  638. if (ltRow) {
  639. ltRow.style.setProperty('display', 'none', 'important');
  640. if (removeElementsTimer) {
  641. workerTimer.clearInterval(removeElementsTimer);
  642. removeElementsTimer = null;
  643. }
  644. }
  645. if (30 <= removeElementsTimerCount && removeElementsTimer) {
  646. workerTimer.clearInterval(removeElementsTimer);
  647. removeElementsTimer = null;
  648. }
  649. }, 10e3);
  650. },
  651. loadData = () => {
  652. let obj = getGmValue(roomId, null);
  653. if (obj) {
  654. if (source.version === obj.version) {
  655. source = obj;
  656. }
  657. else if (obj.version === 2) {
  658. source.data1 = obj.data1;
  659. source.data2 = obj.data2;
  660. source.data3 = obj.data3;
  661. source.data4 = obj.data4;
  662. source.data5 = obj.data5;
  663. setGmValue(roomId, source);
  664. } else {
  665. source.data1.values = obj.data1 ? obj.data1 : source.data1.values;
  666. source.data2.values = obj.data2 ? obj.data2 : source.data2.values;
  667. source.data3.values = obj.data3 ? obj.data3 : source.data3.values;
  668. source.data4.values = obj.data4 ? obj.data4 : source.data4.values;
  669. source.data5.values = obj.data5 ? obj.data5 : source.data5.values;
  670. setGmValue(roomId, source);
  671. }
  672. }
  673.  
  674. setCheckboxChecked();
  675. dataText1.value = source.data1.values.join('|');
  676. dataText2.value = source.data2.values.join('|');
  677. dataText3.value = source.data3.values.join('|');
  678. dataText4.value = source.data4.values.join('|');
  679. dataText5.value = source.data5.values.join('|');
  680. initData();
  681. },
  682. // heartBeat = async () => {
  683. // const arg = `${hbInterval}|${roomId}|1|0`;
  684. // // const argBase64 = CryptoJS ? CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(arg)) : window.btoa(unescape(encodeURIComponent(arg)));
  685. // const argBase64 = window.btoa(unescape(encodeURIComponent(arg)));
  686. // try {
  687. // const result = await fetch(`//live-trace.bilibili.com/xlive/rdata-interface/v1/heartbeat/webHeartBeat?hb=${encodeURIComponent(argBase64)}&pf=web`, {
  688. // mode: 'cors',
  689. // credentials: 'include',
  690. // }).then(res => res.json());
  691. // if (0 === result.code) {
  692. // hbInterval = result.data.next_interval;
  693. // } else {
  694. // console.error(`===> ${roomId}直播间心跳失败`);
  695. // }
  696. // } catch (error) {
  697. // console.error(`===> ${roomId}直播间心跳网络请求失败`, error);
  698. // }
  699.  
  700. // let hbTimer = workerTimer.setTimeout(() => {
  701. // workerTimer.clearTimeout(hbTimer);
  702. // heartBeat();
  703. // }, hbInterval * 1e3);
  704. // },
  705. initSettingPanel = () => {
  706. let settingPanel = document.getElementById('danmu-setting-panel');
  707. if (!settingPanel) {
  708. console.log('===> 进行面板初始化');
  709. let divButton = document.getElementsByClassName('bottom-actions p-relative')[0];
  710. if (divButton) {
  711. buildPanel(divButton);
  712. loadData();
  713. console.log('===> 面板初始化完成');
  714. } else {
  715. console.warn('===> bottom-actions节点丢失');
  716. return false;
  717. }
  718. }
  719.  
  720. return true;
  721. },
  722. noSleep = () => {
  723. workerTimer.setInterval(() => {
  724. let noSleepTimeouter = workerTimer.setTimeout(() => {
  725. workerTimer.clearTimeout(noSleepTimeouter);
  726. document.body.dispatchEvent(new MouseEvent("mousemove", { bubbles: true }));
  727. }, Math.random() * 3e3);
  728. }, 17e3);
  729. },
  730. biliMiniClose = () => {
  731. if (!miniCloseTimer) {
  732. let miniCloseCount = 3;
  733. miniCloseTimer = workerTimer.setInterval(() => {
  734. let mini_close = document.getElementsByClassName('bili-mini-close')[0];
  735. if (!mini_close) {
  736. if (0 >= --miniCloseCount) {
  737. workerTimer.clearInterval(miniCloseTimer);
  738. miniCloseTimer = null;
  739. }
  740.  
  741. return;
  742. }
  743.  
  744. mini_close.click();
  745. workerTimer.clearInterval(miniCloseTimer);
  746. miniCloseTimer = null;
  747. }, 10e3);
  748. }
  749. },
  750. lucky = () => {
  751. let luckyCount = 0;
  752. workerTimer.setInterval(() => {
  753. console.log('===> 第【' + ++luckyCount + '】次定时检查元素');
  754. let abababa = document.getElementsByClassName('particitation-btn bg-100 join-btn-1')[0];
  755. if (!abababa) {
  756. console.log('===> 尝试直接获取抽奖按钮,但失败');
  757. }
  758.  
  759. let anchor_guest_box = document.getElementById('anchor-guest-box-id');
  760. if (!anchor_guest_box) {
  761. return;
  762. }
  763.  
  764. console.log('===> 存在div id=anchor-guest-box-id');
  765. // let close_btn = document.getElementsByClassName('close-btn bg-contain')[0];
  766. // close_btn.click();
  767. let iframe = anchor_guest_box.getElementsByTagName('iframe')[0];
  768. if (!iframe) {
  769. return;
  770. }
  771. console.log('===> 获取到iframe节点');
  772. let iframeDocument = iframe.contentDocument;
  773. if (iframeDocument) {
  774. console.log('===> 获取到iframe document');
  775. }
  776.  
  777. let iframeWindow = iframe.contentWindow;
  778. if (iframeWindow) {
  779. console.log('===> 获取到iframe window');
  780. if (!iframeDocument) {
  781. console.log('===> 尝试从iframe window获取document');
  782. iframeDocument = iframeWindow.document;
  783. if (iframeDocument) {
  784. console.log('===> 从iframe window获取document成功');
  785. }
  786. }
  787. }
  788. if (!iframeDocument) {
  789. console.log('===> iframe document获取不成功');
  790. return;
  791. }
  792.  
  793. let join_btn = iframeDocument.getElementsByClassName('particitation-btn bg-100 join-btn-1')[0];
  794. if (!join_btn) {
  795. console.log('===> 获取不到抽奖按钮');
  796. return;
  797. }
  798.  
  799. console.log('===> 拿到抽奖按钮,我要参加抽奖!!!!');
  800. join_btn.click();
  801. biliMiniClose();
  802. }, 8e3);
  803. },
  804. runStart = () => {
  805. noSleep();
  806. lucky();
  807. if (isOldVersion()) {
  808. window.location.href = parentUrl;
  809. return;
  810. }
  811.  
  812. waiters[waiters.length] = workerTimer.setInterval(() => {
  813. if (initSettingPanel()) {
  814. clearWaiters();
  815. removeElements();
  816. signIn();
  817. // heartBeat();
  818. console.log('===> 运行成功');
  819. } else {
  820. --waitCount;
  821. if (0 >= waitCount) {
  822. clearWaiters();
  823. console.log('===> 创建面板失败,停止初始化');
  824. }
  825. }
  826. }, 1.5e3);
  827. };
  828.  
  829. initCss();
  830. // initScript();
  831. window.runStart = runStart;
  832. window.arrayInfo = arrayInfo;
  833. window.setGmNotice = setGmNotice;
  834. window.setGmGetValue = setGmGetValue;
  835. window.setGmSetValue = setGmSetValue;
  836. window.setGmDelValue = setGmDelValue;
  837. window.setParentData = setParentData;
  838. window.autoSendDanmuModuleLoaded = true;
  839. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址