Bilibili Live Tasks Helper

Enhancing the experience of watching Bilibili live streaming.

  1. // ==UserScript==
  2. // @name Bilibili Live Tasks Helper
  3. // @name:en Bilibili Live Tasks Helper
  4. // @name:zh Bilibili Live Tasks Helper
  5. // @namespace https://github.com/andywang425
  6. // @version 7.1.9
  7. // @author andywang425
  8. // @description Enhancing the experience of watching Bilibili live streaming.
  9. // @description:en Enhancing the experience of watching Bilibili live streaming.
  10. // @description:zh 增强Bilibili直播观看体验。
  11. // @license MIT
  12. // @copyright 2024, andywang425 (https://github.com/andywang425)
  13. // @icon data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDEuMDY1IiBoZWlnaHQ9IjEyNy43NDciIHZpZXdCb3g9IjAgMCAzNy4zMjQgMzMuOCI+PHBhdGggZmlsbD0iIzIwYjBlMyIgZD0iTTg2Ljk2MiAxMTIuMzMyYTIuNjYxIDIuNjYxIDAgMCAxIDIuMjYyIDAgNS41MzYgNS41MzYgMCAwIDEgMS4zODQgMS4wMTFsNS4zMjMgNC42NThoMy44MDVsNS4zMjMtNC42NThhNS41ODkgNS41ODkgMCAwIDEgMS4zODQtMS4wMTEgMi42NjEgMi42NjEgMCAwIDEgMy41NCAyLjIwOSAyLjY2MSAyLjY2MSAwIDAgMS0uNTg2IDEuNzgzIDE0Ljg3NyAxNC44NzcgMCAwIDEtMS4xNzEgMS4wNjUgNy42OTEgNy42OTEgMCAwIDEtLjc0NS42MTJoMy4zMjZhNS42NDIgNS42NDIgMCAwIDEgMy45MTIgMS43NTYgNS42NjkgNS42NjkgMCAwIDEgMS43ODQgMy45MTJ2MTUuMzAzYTEwLjc3OCAxMC43NzggMCAwIDEtLjEzNCAyLjMxNSA1LjkwOCA1LjkwOCAwIDAgMS0yLjY2IDMuNzI2IDUuNzIyIDUuNzIyIDAgMCAxLTMuMDYxLjg1Mkg4Ni4yMTdhMTEuMjg0IDExLjI4NCAwIDAgMS0yLjM5Ni0uMTMzIDUuODgyIDUuODgyIDAgMCAxLTMuNjcyLTIuNjYyIDUuNjk1IDUuNjk1IDAgMCAxLS45MDUtMy4wNnYtMTUuMTQzYTExLjkyMyAxMS45MjMgMCAwIDEgMC0yLjIwOSA1Ljg1NSA1Ljg1NSAwIDAgMSA1LjMyMy00LjczN2gzLjQ4NmMtLjU1OS0uNC0xLjAzOC0uODc4LTEuNTQ0LTEuMzA0YTIuNjYxIDIuNjYxIDAgMCAxLS44NTEtMi4xODMgMi42NjEgMi42NjEgMCAwIDEgMS4zMDQtMi4xMDJtLS42MTIgMTAuMzI2YTIuNjYxIDIuNjYxIDAgMCAwLTIuMTAzIDEuOTE2IDMuNTkzIDMuNTkzIDAgMCAwIDAgMS4wMTF2MTIuNTg4YTIuNjYxIDIuNjYxIDAgMCAwIDEuODM3IDIuNjYyIDMuNTEzIDMuNTEzIDAgMCAwIDEuMTQ0LjE4NmgyMS42MzdhMi42NjEgMi42NjEgMCAwIDAgMi41MjgtMS41NyAzLjcyNiAzLjcyNiAwIDAgMCAuMjY2LTEuNzU3di0xMS43MWE0LjQ3MSA0LjQ3MSAwIDAgMCAwLTEuMjc3IDIuNjYxIDIuNjYxIDAgMCAwLTEuNzMtMS44MSA0LjI4NSA0LjI4NSAwIDAgMC0xLjY1LS4yMzlIODcuNjAxYTguODg5IDguODg5IDAgMCAwLTEuMjUxIDB6bTAgMCIgc3R5bGU9InN0cm9rZS13aWR0aDouMDMzMDcyOSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTc5LjE5MyAtMTEyLjA4KSIvPjxwYXRoIGQ9Ik04OC45NyAxMjguNjM2Yy4zNjMuMzc3Ljc0NS43NDcgMS4wODggMS4xNDIuNTk3LjY4NyAxLjExOCAxLjE5NyAxLjY2NiAxLjgwOS0uMTI5LTEuMTE3IDEuMzA0LTEuMTk4LjA3NC0xLjc1Ny0uNDA4LjQxNy0uOTQxLjg4NC0xLjM2IDEuMjIzLS4zOTIuMzE2LS44NjMuNjctMS4yMzUuOTUyLTEuOTA3IDEuNDQzLjIyNiA0LjA1MyAyLjEzIDIuNjA3IDAgMCAyLTEuNTM1IDIuODA3LTIuMzAxLjQ0LS40MTcuNjgtLjk1Ni43Mi0xLjU5Mi4wNC0uNjU0LS41MzUtMS4yNC0uNzk0LTEuNDk4LS45Mi0uOTE0LTEuNzQzLTEuOTY4LTIuNTUtMi44MTItMS41NzUtMS44LTQuMTIuNDI4LTIuNTQ2IDIuMjI3ek0xMDYuOTc5IDEyOC42MzZjLS4zNjMuMzc3LS43NDUuNzQ3LTEuMDg4IDEuMTQyLS41OTcuNjg3LTEuMTE4IDEuMTk3LTEuNjY2IDEuODA5LjEyOS0xLjExNy0xLjMwNC0xLjE5OC0uMDc0LTEuNzU3LjQwOC40MTcuOTQxLjg4NCAxLjM2IDEuMjIzLjM5Mi4zMTYuODYzLjY3IDEuMjM1Ljk1MiAxLjkwNyAxLjQ0My0uMjI2IDQuMDUzLTIuMTMgMi42MDcgMCAwLTItMS41MzUtMi44MDctMi4zMDEtLjQ0LS40MTctLjY4LS45NTYtLjcyLTEuNTkyLS4wNC0uNjU0LjUzNS0xLjI0Ljc5NC0xLjQ5OC45Mi0uOTE0IDEuNzQzLTEuOTY4IDIuNTUtMi44MTIgMS41NzUtMS44IDQuMTIuNDI4IDIuNTQ2IDIuMjI3eiIgc3R5bGU9ImZpbGw6IzIwYjBlMztmaWxsLW9wYWNpdHk6MTtzdHJva2Utd2lkdGg6LjUyNDE1OTtzdHJva2UtZGFzaGFycmF5Om5vbmUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC03OS4xOTMgLTExMi4wOCkiLz48L3N2Zz4NCg==
  14. // @homepageURL https://github.com/andywang425/BLTH
  15. // @supportURL https://github.com/andywang425/BLTH/issues
  16. // @match *://live.bilibili.com/1*
  17. // @match *://live.bilibili.com/2*
  18. // @match *://live.bilibili.com/3*
  19. // @match *://live.bilibili.com/4*
  20. // @match *://live.bilibili.com/5*
  21. // @match *://live.bilibili.com/6*
  22. // @match *://live.bilibili.com/7*
  23. // @match *://live.bilibili.com/8*
  24. // @match *://live.bilibili.com/9*
  25. // @match *://live.bilibili.com/blanc/1*
  26. // @match *://live.bilibili.com/blanc/2*
  27. // @match *://live.bilibili.com/blanc/3*
  28. // @match *://live.bilibili.com/blanc/4*
  29. // @match *://live.bilibili.com/blanc/5*
  30. // @match *://live.bilibili.com/blanc/6*
  31. // @match *://live.bilibili.com/blanc/7*
  32. // @match *://live.bilibili.com/blanc/8*
  33. // @match *://live.bilibili.com/blanc/9*
  34. // @require https://unpkg.com/vue@3.5.10/dist/vue.global.prod.js
  35. // @require data:application/javascript,%3Bwindow.Vue%3DVue%3Bwindow.VueDemi%3DVue%3B
  36. // @require https://unpkg.com/element-plus@2.8.4/dist/index.full.min.js
  37. // @require https://unpkg.com/@element-plus/icons-vue@2.3.1/dist/index.iife.min.js
  38. // @require https://unpkg.com/pinia@2.2.3/dist/pinia.iife.prod.js
  39. // @require https://unpkg.com/vue-draggable-plus@0.5.3/dist/vue-draggable-plus.iife.js
  40. // @require https://unpkg.com/lodash@4.17.21/lodash.min.js
  41. // @require https://unpkg.com/hotkeys-js@3.13.7/dist/hotkeys.min.js
  42. // @require https://unpkg.com/luxon@3.5.0/build/global/luxon.min.js
  43. // @require https://unpkg.com/crypto-js@4.2.0/crypto-js.js
  44. // @resource element-plus/dist/index.css https://unpkg.com/element-plus@2.8.4/dist/index.css
  45. // @connect api.bilibili.com
  46. // @connect api.live.bilibili.com
  47. // @connect api.vc.bilibili.com
  48. // @connect passport.bilibili.com
  49. // @connect live.bilibili.com
  50. // @connect live-trace.bilibili.com
  51. // @grant GM_addStyle
  52. // @grant GM_getResourceText
  53. // @grant GM_getValue
  54. // @grant GM_setValue
  55. // @grant GM_xmlhttpRequest
  56. // @grant unsafeWindow
  57. // @run-at document-start
  58. // ==/UserScript==
  59.  
  60. (e=>{if(typeof GM_addStyle=="function"){GM_addStyle(e);return}const t=document.createElement("style");t.textContent=e,document.head.append(t)})(" .title[data-v-f383a843]{padding-left:20px;align-items:baseline;display:flex}.header-big-text[data-v-f383a843]{font-size:var(--big-text-size);align-self:unset}.header-small-text[data-v-f383a843]{font-size:var(--small-text-size);align-self:unset;margin-left:10px;--small-text-size: 18px}.collapse-btn[data-v-f383a843]{display:flex;justify-content:center;align-items:center;height:100%;float:left;cursor:pointer}#aside-el-menu[data-v-8ecf0b13]{height:100%}.avatar-wrap[data-v-584fbcd9]{width:80px;height:80px}.avatar[data-v-584fbcd9]{display:flex;justify-content:center;align-items:center;border-radius:50%}.radio-group[data-v-584fbcd9]{display:block;font-size:inherit}.label-text[data-v-1cb0d081]{color:var(--el-text-color-primary);line-height:32px}.base[data-v-24895187]{z-index:1003;position:absolute;background-color:#fff;border-bottom:1px solid #e3e5e7;border-left:1px solid #e3e5e7;border-right:1px solid #e3e5e7}.header[data-v-24895187]{position:relative;box-sizing:border-box;width:100%;font-size:var(--big-text-size);align-items:center;display:flex;border-bottom:1px solid #e3e5e7;height:60px;--big-text-size: 25px}.aside[data-v-24895187]{width:auto}.aside #aside-el-menu[data-v-24895187]:not(.el-menu--collapse){width:150px}.main[data-v-24895187]{--main-top-botton-padding: calc(var(--el-main-padding) * .625);padding-top:var(--main-top-botton-padding);padding-bottom:var(--main-top-botton-padding)}.fade-enter-active[data-v-24895187]{animation:fade-in linear .2s}.info-icon[data-v-38289ed3]{font-size:var(--el-font-size-base);cursor:pointer}.status-icon[data-v-b4254e0f]{font-size:var(--el-font-size-base)}.blth_btn{background-color:#23ade5;font-size:small;margin-inline-start:5px;color:#fff;border-radius:4px;border:none;padding:5px;cursor:pointer;box-shadow:0 0 2px #00000075;line-height:10px;margin-left:15px}.blth_btn:hover{background-color:#1097cc}.blth_btn:hover:active{background-color:#0e86b6;position:relative;top:1px}.el-message-box li{list-style:initial}@media screen and (min-width: 1930px){html[lab-style*=adaptive] .base{zoom:.9375}}@media screen and (min-width: 2058px){html[lab-style*=adaptive] .base{zoom:.75}}@media screen and (min-width: 2570px){html[lab-style*=adaptive] .base{zoom:calc(2 / 3)}}@media screen and (min-width: 3210px){html[lab-style*=adaptive] .base{zoom:.5}}@media screen and (min-width: 3850px){html[lab-style*=adaptive] .base{zoom:.46875}} ");
  61.  
  62. (async function (vue, pinia$1, _, ElementPlusIconsVue, CryptoJS, luxon, ElementPlus, vueDraggablePlus, hotkeys) {
  63. 'use strict';
  64.  
  65. function _interopNamespaceDefault(e) {
  66. const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
  67. if (e) {
  68. for (const k in e) {
  69. if (k !== 'default') {
  70. const d = Object.getOwnPropertyDescriptor(e, k);
  71. Object.defineProperty(n, k, d.get ? d : {
  72. enumerable: true,
  73. get: () => e[k]
  74. });
  75. }
  76. }
  77. }
  78. n.default = e;
  79. return Object.freeze(n);
  80. }
  81.  
  82. const ElementPlusIconsVue__namespace = /*#__PURE__*/_interopNamespaceDefault(ElementPlusIconsVue);
  83.  
  84. var __defProp = Object.defineProperty;
  85. var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  86. var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
  87. var _GM_addStyle = /* @__PURE__ */ (() => typeof GM_addStyle != "undefined" ? GM_addStyle : void 0)();
  88. var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)();
  89. var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)();
  90. var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0)();
  91. var _unsafeWindow = /* @__PURE__ */ (() => typeof unsafeWindow != "undefined" ? unsafeWindow : void 0)();
  92. const defaultValues = {
  93. ui: {
  94. isCollapse: false,
  95. isShowPanel: true,
  96. activeMenuIndex: "MainSiteTasks",
  97. panelWidthPercent: 40,
  98. medalInfoPanelSortMode: false
  99. },
  100. modules: {
  101. DailyTasks: {
  102. MainSiteTasks: {
  103. login: {
  104. enabled: false,
  105. _lastCompleteTime: 0
  106. },
  107. watch: {
  108. enabled: false,
  109. _lastCompleteTime: 0
  110. },
  111. coin: {
  112. enabled: false,
  113. num: 1,
  114. _lastCompleteTime: 0
  115. },
  116. share: {
  117. enabled: false,
  118. _lastCompleteTime: 0
  119. }
  120. },
  121. LiveTasks: {
  122. sign: {
  123. enabled: false,
  124. _lastCompleteTime: 0
  125. },
  126. medalTasks: {
  127. light: {
  128. enabled: false,
  129. mode: "danmu",
  130. danmuList: [
  131. "(⌒▽⌒)",
  132. "( ̄▽ ̄)",
  133. "(=・ω・=)",
  134. "(`・ω・´)",
  135. "(〜 ̄△ ̄)〜",
  136. "(・∀・)",
  137. "(°∀°)ノ",
  138. "╮( ̄▽ ̄)╭",
  139. "_(:3」∠)_",
  140. "(^・ω・^ )",
  141. "(● ̄(エ) ̄●)",
  142. "ε=ε=(ノ≧∇≦)ノ",
  143. "⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄",
  144. "←◡←",
  145. `(●'◡'●)ノ♥`
  146. ],
  147. _lastCompleteTime: 0
  148. },
  149. watch: {
  150. enabled: false,
  151. time: 25,
  152. _watchingProgress: {},
  153. _lastWatchTime: 0,
  154. _lastCompleteTime: 0
  155. },
  156. isWhiteList: false,
  157. roomidList: []
  158. }
  159. },
  160. OtherTasks: {
  161. groupSign: {
  162. enabled: false,
  163. _lastCompleteTime: 0
  164. },
  165. silverToCoin: {
  166. enabled: false,
  167. _lastCompleteTime: 0
  168. },
  169. coinToSilver: {
  170. enabled: false,
  171. num: 1,
  172. _lastCompleteTime: 0
  173. },
  174. getYearVipPrivilege: {
  175. enabled: false,
  176. _nextReceiveTime: 0
  177. }
  178. }
  179. },
  180. EnhanceExperience: {
  181. switchLiveStreamQuality: {
  182. enabled: false,
  183. qualityDesc: "原画"
  184. },
  185. banp2p: {
  186. enabled: false
  187. },
  188. noReport: {
  189. enabled: false
  190. },
  191. noSleep: {
  192. enabled: false
  193. },
  194. invisibility: {
  195. enabled: false
  196. }
  197. },
  198. RemoveElement: {
  199. removePKBox: {
  200. enabled: false
  201. },
  202. removeLiveWaterMark: {
  203. enabled: false
  204. },
  205. removeShopPopover: {
  206. enabled: false
  207. },
  208. removeGameParty: {
  209. enabled: false
  210. },
  211. removeGiftPopover: {
  212. enabled: false
  213. },
  214. removeMicPopover: {
  215. enabled: false
  216. },
  217. removeComboCard: {
  218. enabled: false
  219. },
  220. removeRank: {
  221. enabled: false
  222. },
  223. removeHeaderStuff: {
  224. enabled: false
  225. },
  226. removeFlipView: {
  227. enabled: false
  228. },
  229. removeRecommendRoom: {
  230. enabled: false
  231. },
  232. removeLiveMosaic: {
  233. enabled: false
  234. }
  235. }
  236. },
  237. cache: {
  238. lastAliveHeartBeatTime: 0
  239. }
  240. };
  241. class Storage {
  242. /**
  243. * 递归合并配置项。删除当前配置中不存在于默认配置的键,补上相对于默认配置缺少的键值,其它键值不变
  244. *
  245. * 该方法不会修改当前配置
  246. *
  247. * @param currentConfig 当前配置
  248. * @param defaultConfig 默认配置
  249. * @returns 修改后的当前配置
  250. * @example
  251. *
  252. * const current_config = { enabled: true, details: { type: 'efg', status: 'ok' }, msg: 'hi' };
  253. * const default_config = { enabled: false, details: { type: 'abc', num: 1 } };
  254. *
  255. * mergeConfigs(current_config, default_config);
  256. * // => { enabled: true, details: { type: 'efg', num: 1 } }
  257. */
  258. static mergeConfigs(currentConfig, defaultConfig) {
  259. const config = _.pick(currentConfig, _.keys(defaultConfig));
  260. _.defaults(config, defaultConfig);
  261. _.forOwn(config, (value, key, object) => {
  262. if (_.isPlainObject(value) && _.isPlainObject(defaultConfig[key]) && !_.isEmpty(defaultConfig[key])) {
  263. object[key] = this.mergeConfigs(value, defaultConfig[key]);
  264. }
  265. });
  266. return config;
  267. }
  268. static setUiConfig(uiConfig) {
  269. _GM_setValue("ui", uiConfig);
  270. }
  271. static getUiConfig() {
  272. return this.mergeConfigs(_GM_getValue("ui", {}), defaultValues.ui);
  273. }
  274. static setModuleConfig(moduleConfig) {
  275. _GM_setValue("modules", moduleConfig);
  276. }
  277. static getModuleConfig() {
  278. return this.mergeConfigs(_GM_getValue("modules", {}), defaultValues.modules);
  279. }
  280. static setCache(cache) {
  281. _GM_setValue("cache", cache);
  282. }
  283. static getCache() {
  284. return this.mergeConfigs(_GM_getValue("cache", {}), defaultValues.cache);
  285. }
  286. }
  287. const index2name = {
  288. MainSiteTasks: "主站任务",
  289. LiveTasks: "直播任务",
  290. OtherTasks: "其它任务",
  291. EnhanceExperience: "体验优化",
  292. RemoveElement: "移除元素",
  293. ScriptSettings: "设置"
  294. };
  295. const useUIStore = pinia$1.defineStore("ui", () => {
  296. const uiConfig = vue.reactive(Storage.getUiConfig());
  297. const activeMenuName = vue.computed(() => index2name[uiConfig.activeMenuIndex]);
  298. const livePlayerRect = vue.reactive({
  299. top: 0,
  300. left: 0,
  301. height: 0,
  302. width: 0
  303. });
  304. const windowScrollPosition = vue.reactive({ x: 0, y: 0 });
  305. const panelStyle = vue.computed(() => ({
  306. // 此处若使用最新的滚动条位置(window.scrollX/Y),用户在调整控制面板宽度时可能导致面板在垂直方向上错位
  307. top: `${livePlayerRect.top + windowScrollPosition.y}px`,
  308. left: `${livePlayerRect.left + windowScrollPosition.x}px`,
  309. height: `${livePlayerRect.height}px`,
  310. width: `${livePlayerRect.width * uiConfig.panelWidthPercent / 100}px`
  311. }));
  312. const isShowPanelButtonText = vue.computed(
  313. () => uiConfig.isShowPanel ? "隐藏控制面板" : "显示控制面板"
  314. );
  315. const scrollBarHeight = vue.computed(() => `${livePlayerRect.height - 60}px`);
  316. function changeCollapse() {
  317. uiConfig.isCollapse = !uiConfig.isCollapse;
  318. }
  319. function changeShowPanel() {
  320. uiConfig.isShowPanel = !uiConfig.isShowPanel;
  321. }
  322. function setActiveMenuIndex(index) {
  323. uiConfig.activeMenuIndex = index;
  324. }
  325. vue.watch(
  326. uiConfig,
  327. _.debounce((newUiConfig) => Storage.setUiConfig(newUiConfig), 350)
  328. );
  329. return {
  330. isShowPanelButtonText,
  331. activeMenuName,
  332. livePlayerRect,
  333. windowScrollPosition,
  334. panelStyle,
  335. scrollBarHeight,
  336. uiConfig,
  337. changeCollapse,
  338. changeShowPanel,
  339. setActiveMenuIndex
  340. };
  341. });
  342. const _hoisted_1$2 = { class: "title" };
  343. const _sfc_main$c = /* @__PURE__ */ vue.defineComponent({
  344. __name: "PanelHeader",
  345. setup(__props) {
  346. const uiStore = useUIStore();
  347. return (_ctx, _cache) => {
  348. const _component_el_icon = vue.resolveComponent("el-icon");
  349. const _component_el_text = vue.resolveComponent("el-text");
  350. return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
  351. vue.createElementVNode("div", {
  352. class: "collapse-btn",
  353. onClick: _cache[0] || (_cache[0] = //@ts-ignore
  354. (...args) => vue.unref(uiStore).changeCollapse && vue.unref(uiStore).changeCollapse(...args))
  355. }, [
  356. vue.unref(uiStore).uiConfig.isCollapse ? (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 0 }, {
  357. default: vue.withCtx(() => [
  358. vue.createVNode(vue.unref(ElementPlusIconsVue.Expand))
  359. ]),
  360. _: 1
  361. })) : (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 1 }, {
  362. default: vue.withCtx(() => [
  363. vue.createVNode(vue.unref(ElementPlusIconsVue.Fold))
  364. ]),
  365. _: 1
  366. }))
  367. ]),
  368. vue.createElementVNode("div", _hoisted_1$2, [
  369. vue.createVNode(_component_el_text, {
  370. tag: "b",
  371. class: "header-big-text"
  372. }, {
  373. default: vue.withCtx(() => _cache[1] || (_cache[1] = [
  374. vue.createTextVNode("控制面板")
  375. ])),
  376. _: 1
  377. }),
  378. vue.createVNode(_component_el_text, { class: "header-small-text" }, {
  379. default: vue.withCtx(() => [
  380. vue.createTextVNode(vue.toDisplayString(vue.unref(uiStore).activeMenuName), 1)
  381. ]),
  382. _: 1
  383. })
  384. ])
  385. ], 64);
  386. };
  387. }
  388. });
  389. const _export_sfc = (sfc, props) => {
  390. const target = sfc.__vccOpts || sfc;
  391. for (const [key, val] of props) {
  392. target[key] = val;
  393. }
  394. return target;
  395. };
  396. const PanelHeader = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["__scopeId", "data-v-f383a843"]]);
  397. const _sfc_main$b = /* @__PURE__ */ vue.defineComponent({
  398. __name: "PanelAside",
  399. setup(__props) {
  400. const uiStore = useUIStore();
  401. const items = [
  402. {
  403. icon: "Tasks",
  404. title: "每日任务",
  405. index: "DailyTasks",
  406. // 有子菜单,index 无所谓
  407. subs: [
  408. {
  409. title: "主站任务",
  410. index: "MainSiteTasks"
  411. // index 是组件名
  412. },
  413. {
  414. title: "直播任务",
  415. index: "LiveTasks"
  416. },
  417. {
  418. title: "其它任务",
  419. index: "OtherTasks"
  420. }
  421. ]
  422. },
  423. {
  424. icon: "Monitor",
  425. title: "体验优化",
  426. index: "EnhanceExperience"
  427. },
  428. {
  429. icon: "Scissor",
  430. title: "移除元素",
  431. index: "RemoveElement"
  432. },
  433. {
  434. icon: "Setting",
  435. title: "设置",
  436. index: "ScriptSettings"
  437. }
  438. ];
  439. return (_ctx, _cache) => {
  440. const _component_el_icon = vue.resolveComponent("el-icon");
  441. const _component_el_menu_item = vue.resolveComponent("el-menu-item");
  442. const _component_el_sub_menu = vue.resolveComponent("el-sub-menu");
  443. const _component_el_menu = vue.resolveComponent("el-menu");
  444. return vue.openBlock(), vue.createBlock(_component_el_menu, {
  445. "default-active": vue.unref(uiStore).uiConfig.activeMenuIndex,
  446. style: vue.normalizeStyle({ "min-height": vue.unref(uiStore).scrollBarHeight }),
  447. collapse: vue.unref(uiStore).uiConfig.isCollapse,
  448. "unique-opened": "",
  449. onSelect: _cache[0] || (_cache[0] = (index) => vue.unref(uiStore).setActiveMenuIndex(index)),
  450. id: "aside-el-menu"
  451. }, {
  452. default: vue.withCtx(() => [
  453. (vue.openBlock(), vue.createElementBlock(vue.Fragment, null, vue.renderList(items, (item) => {
  454. return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
  455. item.subs ? (vue.openBlock(), vue.createBlock(_component_el_sub_menu, {
  456. index: item.index,
  457. key: item.index
  458. }, {
  459. title: vue.withCtx(() => [
  460. vue.createVNode(_component_el_icon, null, {
  461. default: vue.withCtx(() => [
  462. (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(item.icon)))
  463. ]),
  464. _: 2
  465. }, 1024),
  466. vue.createElementVNode("span", null, vue.toDisplayString(item.title), 1)
  467. ]),
  468. default: vue.withCtx(() => [
  469. (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(item.subs, (subItem) => {
  470. return vue.openBlock(), vue.createBlock(_component_el_menu_item, {
  471. index: subItem.index,
  472. key: subItem.index
  473. }, {
  474. default: vue.withCtx(() => [
  475. vue.createTextVNode(vue.toDisplayString(subItem.title), 1)
  476. ]),
  477. _: 2
  478. }, 1032, ["index"]);
  479. }), 128))
  480. ]),
  481. _: 2
  482. }, 1032, ["index"])) : (vue.openBlock(), vue.createBlock(_component_el_menu_item, {
  483. index: item.index,
  484. key: item.index
  485. }, {
  486. title: vue.withCtx(() => [
  487. vue.createTextVNode(vue.toDisplayString(item.title), 1)
  488. ]),
  489. default: vue.withCtx(() => [
  490. vue.createVNode(_component_el_icon, null, {
  491. default: vue.withCtx(() => [
  492. (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(item.icon)))
  493. ]),
  494. _: 2
  495. }, 1024)
  496. ]),
  497. _: 2
  498. }, 1032, ["index"]))
  499. ], 64);
  500. }), 64))
  501. ]),
  502. _: 1
  503. }, 8, ["default-active", "style", "collapse"]);
  504. };
  505. }
  506. });
  507. const PanelAside = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["__scopeId", "data-v-8ecf0b13"]]);
  508. luxon.Settings.defaultZone = "Asia/Shanghai";
  509. function isTimestampToday(timestamp, hour = 0, minute = 5) {
  510. const time = luxon.DateTime.fromMillis(timestamp);
  511. const startOfADay = luxon.DateTime.now().set({
  512. hour,
  513. minute,
  514. second: 0,
  515. millisecond: 0
  516. });
  517. const startOfTomorrow = startOfADay.plus({ days: 1 });
  518. const startOfYesterday = startOfADay.minus({ days: 1 });
  519. if (luxon.DateTime.now() >= startOfADay) {
  520. return time >= startOfADay && time < startOfTomorrow;
  521. } else {
  522. return time >= startOfYesterday && time < startOfADay;
  523. }
  524. }
  525. function delayToNextMoment(hour = 0, minute = 5) {
  526. const now = luxon.DateTime.now();
  527. let nextTime = luxon.DateTime.local(now.year, now.month, now.day, hour, minute);
  528. if (now > nextTime) {
  529. nextTime = nextTime.plus({ days: 1 });
  530. }
  531. const diff = nextTime.diff(now);
  532. return {
  533. // 时间戳
  534. ms: diff.toMillis(),
  535. // 便于阅读的字符串,去掉开头的0小时和0分钟
  536. str: diff.toFormat("h小时m分钟s秒").replace(/^0小时/, "").replace(/^0分钟/, "")
  537. };
  538. }
  539. function isNowIn(startHour, startMinute, endHour, endMinute) {
  540. const now = luxon.DateTime.now();
  541. const start = luxon.DateTime.local(now.year, now.month, now.day, startHour, startMinute);
  542. let end = luxon.DateTime.local(now.year, now.month, now.day, endHour, endMinute);
  543. if (start > end) {
  544. end = end.plus({ days: 1 });
  545. }
  546. return now >= start && now < end;
  547. }
  548. function ts() {
  549. return Math.round(luxon.DateTime.now().toSeconds());
  550. }
  551. function tsm() {
  552. return luxon.DateTime.now().toMillis();
  553. }
  554. function uuid() {
  555. return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(char) {
  556. const randomInt = 16 * Math.random() | 0;
  557. return ("x" === char ? randomInt : 3 & randomInt | 8).toString(16);
  558. });
  559. }
  560. function sleep(miliseconds) {
  561. return new Promise((resolve2) => setTimeout(resolve2, miliseconds));
  562. }
  563. function getFilenameFromUrl(url) {
  564. return url.substring(url.lastIndexOf("/") + 1).split(".")[0];
  565. }
  566. function addURLParams(url, params) {
  567. if (!params) {
  568. return url;
  569. }
  570. if (typeof params === "string") {
  571. return url + "?" + params;
  572. } else {
  573. return url + "?" + new URLSearchParams(params).toString();
  574. }
  575. }
  576. function wbiSign(params) {
  577. params.wts = ts();
  578. const query = Object.keys(params).sort().map((key) => {
  579. const value = params[key].toString().replace(/[!'()*]/g, "");
  580. return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
  581. }).join("&");
  582. const wbiSign2 = CryptoJS.MD5(query + useBiliStore().wbiSalt).toString();
  583. return query + "&w_rid=" + wbiSign2;
  584. }
  585. function packFormData(json) {
  586. const formData = new FormData();
  587. _.forEach(json, (value, key) => formData.append(key, value.toString()));
  588. return formData;
  589. }
  590. function deepestIterate(obj, fn, path) {
  591. _.forOwn(obj, function(value, key) {
  592. const newPath = path ? path + "." + key : key;
  593. if (_.isPlainObject(value) && !_.isEmpty(value)) {
  594. deepestIterate(value, fn, newPath);
  595. } else {
  596. fn(value, newPath);
  597. }
  598. });
  599. }
  600. function getUrlFromFetchInput(input) {
  601. if (typeof input === "string") {
  602. return input;
  603. } else if (input instanceof URL) {
  604. return input.toString();
  605. } else if (input instanceof Request) {
  606. return input.url;
  607. } else {
  608. return "Incorrect input";
  609. }
  610. }
  611. function waitForMoment(moment) {
  612. switch (moment) {
  613. case "document-start": {
  614. return Promise.resolve();
  615. }
  616. case "document-head": {
  617. return new Promise((resolve2) => {
  618. if (document.head) {
  619. resolve2();
  620. } else {
  621. const observer = new MutationObserver(() => {
  622. if (document.head) {
  623. observer.disconnect();
  624. resolve2();
  625. }
  626. });
  627. observer.observe(document.documentElement, { childList: true });
  628. }
  629. });
  630. }
  631. case "document-body": {
  632. return new Promise((resolve2) => {
  633. if (document.body) {
  634. resolve2();
  635. } else {
  636. const observer = new MutationObserver(() => {
  637. if (document.body) {
  638. observer.disconnect();
  639. resolve2();
  640. }
  641. });
  642. observer.observe(document.documentElement, { childList: true });
  643. }
  644. });
  645. }
  646. case "document-end": {
  647. return new Promise((resolve2) => {
  648. if (document.readyState !== "loading") {
  649. resolve2();
  650. } else {
  651. document.addEventListener("DOMContentLoaded", () => resolve2());
  652. }
  653. });
  654. }
  655. case "window-load": {
  656. return new Promise((resolve2) => {
  657. if (document.readyState === "complete") {
  658. resolve2();
  659. } else {
  660. window.addEventListener("load", () => resolve2());
  661. }
  662. });
  663. }
  664. default: {
  665. return Promise.reject("Illegal moment");
  666. }
  667. }
  668. }
  669. function arrayToMap(arr) {
  670. return new Map(arr.map((value, index) => [value, index]));
  671. }
  672. const useBiliStore = pinia$1.defineStore("bili", () => {
  673. const BilibiliLive2 = vue.ref();
  674. const cookies = vue.ref();
  675. const userInfo = vue.ref();
  676. const giftConfig = vue.ref();
  677. const dailyRewardInfo = vue.ref();
  678. const dynamicVideos = vue.ref();
  679. const fansMedals = vue.ref();
  680. const filteredFansMedals = vue.computed(
  681. () => {
  682. var _a;
  683. return ((_a = fansMedals.value) == null ? void 0 : _a.filter((m) => m.room_info.room_id !== 0)) ?? [];
  684. }
  685. );
  686. const fansMedalsStatus = vue.ref();
  687. const wbiSalt = vue.computed(() => {
  688. if (!userInfo.value) {
  689. return "";
  690. }
  691. const imgKey = getFilenameFromUrl(userInfo.value.wbi_img.img_url);
  692. const subKey = getFilenameFromUrl(userInfo.value.wbi_img.sub_url);
  693. const imgAndSubKey = imgKey + subKey;
  694. return [
  695. 46,
  696. 47,
  697. 18,
  698. 2,
  699. 53,
  700. 8,
  701. 23,
  702. 32,
  703. 15,
  704. 50,
  705. 10,
  706. 31,
  707. 58,
  708. 3,
  709. 45,
  710. 35,
  711. 27,
  712. 43,
  713. 5,
  714. 49,
  715. 33,
  716. 9,
  717. 42,
  718. 19,
  719. 29,
  720. 28,
  721. 14,
  722. 39,
  723. 12,
  724. 38,
  725. 41,
  726. 13,
  727. 37,
  728. 48,
  729. 7,
  730. 16,
  731. 24,
  732. 55,
  733. 40,
  734. 61,
  735. 26,
  736. 17,
  737. 0,
  738. 1,
  739. 60,
  740. 51,
  741. 30,
  742. 4,
  743. 22,
  744. 25,
  745. 54,
  746. 21,
  747. 56,
  748. 59,
  749. 6,
  750. 63,
  751. 57,
  752. 62,
  753. 11,
  754. 36,
  755. 20,
  756. 34,
  757. 44,
  758. 52
  759. ].map((n) => imgAndSubKey[n]).join("").slice(0, 32);
  760. });
  761. return {
  762. BilibiliLive: BilibiliLive2,
  763. userInfo,
  764. giftConfig,
  765. cookies,
  766. dailyRewardInfo,
  767. dynamicVideos,
  768. fansMedals,
  769. filteredFansMedals,
  770. fansMedalsStatus,
  771. wbiSalt
  772. };
  773. });
  774. let Request$1 = class Request2 {
  775. constructor(url_prefix, orgin) {
  776. /** 请求 URL 的前缀 */
  777. __publicField(this, "url_prefix");
  778. /**
  779. * 请求 Header 中 Origin 的值,为了方便同时也是 Referer 的值
  780. */
  781. __publicField(this, "origin");
  782. this.url_prefix = url_prefix ?? "";
  783. this.origin = orgin ?? "https://bilibili.com";
  784. }
  785. /**
  786. * 发起一个 GET 请求
  787. * @param url 请求 URL 除去前缀的部分
  788. * @param params URL 参数
  789. * @param otherDetails GM_xmlhttpRequest 的 details 参数
  790. */
  791. get(url, params, otherDetails) {
  792. url = addURLParams(this.url_prefix + url, params);
  793. return new Promise((resolve2, reject2) => {
  794. const defaultDetails = {
  795. method: "GET",
  796. url,
  797. responseType: "json",
  798. headers: {
  799. Accept: "application/json, text/plain, */*",
  800. Referer: this.origin,
  801. Origin: this.origin,
  802. "Sec-Fetch-Site": "same-site"
  803. },
  804. onload: function(response) {
  805. resolve2(response.response);
  806. },
  807. onerror: function(err) {
  808. reject2(new Error(JSON.stringify(err)));
  809. }
  810. };
  811. const details = _.defaultsDeep(otherDetails, defaultDetails);
  812. _GM_xmlhttpRequest(details);
  813. });
  814. }
  815. /**
  816. * 发起一个 POST 请求
  817. * @param url 请求 URL 除去前缀的部分
  818. * @param data POST data
  819. * @param otherDetails GM_xmlhttpRequest 的 details 参数(特别的,可以提供 params 属性作为 URL 参数)
  820. */
  821. post(url, data, otherDetails) {
  822. const headers = {
  823. Accept: "application/json, text/plain, */*",
  824. Referer: this.origin,
  825. Origin: this.origin,
  826. "Sec-Fetch-Site": "same-site",
  827. "Content-Type": "application/x-www-form-urlencoded"
  828. };
  829. if (data instanceof FormData) {
  830. delete headers["Content-Type"];
  831. } else if (typeof data === "object") {
  832. data = new URLSearchParams(data).toString();
  833. }
  834. url = addURLParams(this.url_prefix + url, otherDetails == null ? void 0 : otherDetails.params);
  835. otherDetails == null ? true : delete otherDetails.params;
  836. return new Promise((resolve2, reject2) => {
  837. const defaultDetails = {
  838. method: "POST",
  839. url,
  840. data,
  841. responseType: "json",
  842. headers,
  843. onload: function(response) {
  844. resolve2(response.response);
  845. },
  846. onerror: function(err) {
  847. reject2(new Error(JSON.stringify(err)));
  848. }
  849. };
  850. const details = _.defaultsDeep(otherDetails, defaultDetails);
  851. _GM_xmlhttpRequest(details);
  852. });
  853. }
  854. };
  855. const request = {
  856. live: new Request$1("https://api.live.bilibili.com", "https://live.bilibili.com"),
  857. liveTrace: new Request$1("https://live-trace.bilibili.com", "https://live.bilibili.com"),
  858. passport: new Request$1("https://passport.bilibili.com", "https://passport.bilibili.com/"),
  859. main: new Request$1("https://api.bilibili.com", "https://www.bilibili.com"),
  860. vc: new Request$1("https://api.vc.bilibili.com", "https://message.bilibili.com/"),
  861. raw: new Request$1()
  862. };
  863. const BAPI = {
  864. live: {
  865. roomGiftConfig: (room_id = 0, area_parent_id = 0, area_id = 0, platform = "pc") => {
  866. return request.live.get("/xlive/web-room/v1/giftPanel/roomGiftConfig", {
  867. platform,
  868. room_id,
  869. area_parent_id,
  870. area_id
  871. });
  872. },
  873. doSign: () => {
  874. return request.live.get("/xlive/web-ucenter/v1/sign/DoSign");
  875. },
  876. /**
  877. * 网页直播签到功能已不存在,但该API仍可以使用(并且也存在于B站js代码中)
  878. */
  879. getSignInfo: () => {
  880. return request.live.get("/xlive/web-ucenter/v1/sign/WebGetSignInfo");
  881. },
  882. fansMedalPanel: (page, page_size = 10) => {
  883. return request.live.get("/xlive/app-ucenter/v1/fansMedal/panel", {
  884. page,
  885. page_size
  886. });
  887. },
  888. sendMsg: (msg, roomid, room_type = 0, mode = 1, jumpfrom = 0, fontsize = 25, color = 16777215, bubble = 0, reply_mid = 0, reply_attr = 0, replay_dmid = "", statistics = '{"appId":100,"platform":5}') => {
  889. const biliStore = useBiliStore();
  890. const bili_jct = biliStore.cookies.bili_jct;
  891. return request.live.post(
  892. "/msg/send",
  893. packFormData({
  894. bubble,
  895. msg,
  896. color,
  897. mode,
  898. room_type,
  899. jumpfrom,
  900. reply_mid,
  901. reply_attr,
  902. replay_dmid,
  903. statistics,
  904. fontsize,
  905. rnd: ts(),
  906. roomid,
  907. csrf: bili_jct,
  908. csrf_token: bili_jct
  909. })
  910. );
  911. },
  912. likeReport: (room_id, anchor_id, click_time = 1, visit_id = "") => {
  913. const biliStore = useBiliStore();
  914. const bili_jct = biliStore.cookies.bili_jct;
  915. const uid = biliStore.BilibiliLive.UID;
  916. return request.live.post("/xlive/app-ucenter/v1/like_info_v3/like/likeReportV3", {
  917. click_time,
  918. room_id,
  919. uid,
  920. anchor_id,
  921. csrf_token: bili_jct,
  922. csrf: bili_jct,
  923. visit_id
  924. });
  925. },
  926. /**
  927. * 该API只在带有多层iframe(背景很好看)的直播间中被使用,但参数填任意直播间均可
  928. */
  929. getInfoByRoom: (room_id, web_location = "444.8") => {
  930. return request.live.get(
  931. "/xlive/web-room/v1/index/getInfoByRoom",
  932. wbiSign({
  933. room_id,
  934. web_location
  935. })
  936. );
  937. },
  938. getUserTaskProgress: (target_id = 11153765) => {
  939. const biliStore = useBiliStore();
  940. const bili_jct = biliStore.cookies.bili_jct;
  941. return request.live.get("/xlive/app-ucenter/v1/userTask/GetUserTaskProgress", {
  942. target_id,
  943. csrf: bili_jct,
  944. ts: ts()
  945. });
  946. },
  947. userTaskReceiveRewards: (target_id = 11153765) => {
  948. const biliStore = useBiliStore();
  949. const bili_jct = biliStore.cookies.bili_jct;
  950. return request.live.post("/xlive/app-ucenter/v1/userTask/UserTaskReceiveRewards", {
  951. actionKey: "csrf",
  952. target_id,
  953. csrf: bili_jct,
  954. ts: ts()
  955. });
  956. },
  957. silver2coin: (visit_id = "") => {
  958. const bili_jct = useBiliStore().cookies.bili_jct;
  959. return request.live.post("/xlive/revenue/v1/wallet/silver2coin", {
  960. csrf: bili_jct,
  961. csrf_token: bili_jct,
  962. visit_id
  963. });
  964. },
  965. coin2silver: (num, platform = "pc", visit_id = "") => {
  966. const bili_jct = useBiliStore().cookies.bili_jct;
  967. return request.live.post("/xlive/revenue/v1/wallet/coin2silver", {
  968. num,
  969. csrf: bili_jct,
  970. csrf_token: bili_jct,
  971. platform,
  972. visit_id
  973. });
  974. },
  975. wearMedal: (medal_id, visit_id = "") => {
  976. const bili_jct = useBiliStore().cookies.bili_jct;
  977. return request.live.post("/xlive/web-room/v1/fansMedal/wear", {
  978. medal_id,
  979. csrf_token: bili_jct,
  980. csrf: bili_jct,
  981. visit_id
  982. });
  983. }
  984. },
  985. liveTrace: {
  986. E: (id, device, ruid, is_patch = 0, heart_beat = [], visit_id = "") => {
  987. const bili_jct = useBiliStore().cookies.bili_jct;
  988. return request.liveTrace.post("/xlive/data-interface/v1/x25Kn/E", {
  989. id: JSON.stringify(id),
  990. device: JSON.stringify(device),
  991. ruid,
  992. // 主播 uid
  993. ts: tsm(),
  994. is_patch,
  995. heart_beat: JSON.stringify(heart_beat),
  996. ua: navigator.userAgent,
  997. csrf_token: bili_jct,
  998. csrf: bili_jct,
  999. visit_id
  1000. });
  1001. },
  1002. X: (s, id, device, ruid, ets, benchmark, time, ts2, visit_id = "") => {
  1003. const bili_jct = useBiliStore().cookies.bili_jct;
  1004. return request.liveTrace.post("/xlive/data-interface/v1/x25Kn/X", {
  1005. s,
  1006. id: JSON.stringify(id),
  1007. device: JSON.stringify(device),
  1008. ruid,
  1009. // 主播 uid
  1010. ets,
  1011. benchmark,
  1012. time,
  1013. ts: ts2,
  1014. ua: navigator.userAgent,
  1015. csrf_token: bili_jct,
  1016. csrf: bili_jct,
  1017. visit_id
  1018. });
  1019. }
  1020. },
  1021. main: {
  1022. nav: () => {
  1023. return request.main.get("/x/web-interface/nav");
  1024. },
  1025. reward: () => {
  1026. return request.main.get("/x/member/web/exp/reward");
  1027. },
  1028. dynamicAll: (type = "video", page = 1, timezone_offset = -480, platform = "web", features = "itemOpusStyle,listOnlyfans,opusBigCover,onlyfansVote,decorationCard,onlyfansAssetsV2,forwardListHidden,ugcDelete", web_location = "333.1365", x_bili_device_req_json = '{"platform":"web","device":"pc"}', x_bili_web_req_json = '{"spm_id":"333.1365"}') => {
  1029. return request.main.get(
  1030. "/x/polymer/web-dynamic/v1/feed/all",
  1031. {
  1032. timezone_offset,
  1033. type,
  1034. platform,
  1035. page,
  1036. features,
  1037. web_location,
  1038. x_bili_device_req_json,
  1039. x_bili_web_req_json
  1040. },
  1041. {
  1042. Origin: "https://t.bilibili.com",
  1043. Referer: "https://t.bilibili.com/"
  1044. }
  1045. );
  1046. },
  1047. videoHeartbeat: (aid, cid = 1e9, type = 3, sub_type = 0, dt = 2, play_type = 1, realtime = 61, played_time = 62, real_played_time = 62, refer_url = "https://t.bilibili.com/?tab=video", quality = 64, video_duration = 180, last_play_progress_time = 62, max_play_progress_time = 62, outer = 0, spmid = "333.788.0.0", from_spmid = "333.1365.list.card_archive.click", session = uuid().replaceAll("-", ""), extra = '{"player_version":"4.8.43"}', web_location = 1315873) => {
  1048. const biliStore = useBiliStore();
  1049. const start_ts = ts();
  1050. const mid = useBiliStore().userInfo.mid;
  1051. return request.main.post(
  1052. "/x/click-interface/web/heartbeat",
  1053. {
  1054. start_ts,
  1055. mid,
  1056. aid,
  1057. cid,
  1058. type,
  1059. sub_type,
  1060. dt,
  1061. play_type,
  1062. realtime,
  1063. played_time,
  1064. real_played_time,
  1065. refer_url,
  1066. quality,
  1067. video_duration,
  1068. last_play_progress_time,
  1069. max_play_progress_time,
  1070. outer,
  1071. spmid,
  1072. from_spmid,
  1073. session,
  1074. extra,
  1075. csrf: biliStore.cookies.bili_jct
  1076. },
  1077. {
  1078. params: wbiSign({
  1079. w_start_ts: start_ts,
  1080. w_mid: mid,
  1081. w_aid: aid,
  1082. w_dt: dt,
  1083. w_realtime: realtime,
  1084. w_played_time: played_time,
  1085. w_real_played_time: real_played_time,
  1086. w_video_duration: video_duration,
  1087. w_last_play_progress_time: last_play_progress_time,
  1088. web_location
  1089. })
  1090. }
  1091. );
  1092. },
  1093. share: (aid, source = "pc_client_normal", eab_x = 2, ramval = 0, ga = 1, referer = "") => {
  1094. const bili_jct = useBiliStore().cookies.bili_jct;
  1095. return request.main.post("/x/web-interface/share/add", {
  1096. eab_x,
  1097. ramval,
  1098. referer,
  1099. source,
  1100. aid,
  1101. ga,
  1102. csrf: bili_jct
  1103. });
  1104. },
  1105. coinAdd: (aid, num, select_like = 0, cross_domain = true, eab_x = 2, ramval = 6, source = "web_normal", ga = 1) => {
  1106. const bili_jct = useBiliStore().cookies.bili_jct;
  1107. return request.main.post("/x/web-interface/coin/add ", {
  1108. aid,
  1109. multiply: num,
  1110. select_like,
  1111. cross_domain,
  1112. eab_x,
  1113. ramval,
  1114. source,
  1115. ga,
  1116. csrf: bili_jct
  1117. });
  1118. },
  1119. videoRelation: (aid, bvid = "") => {
  1120. return request.main.get("/x/web-interface/archive/relation", {
  1121. aid,
  1122. bvid
  1123. });
  1124. },
  1125. vip: {
  1126. myPrivilege: (web_location = "333.33") => {
  1127. return request.main.get(
  1128. "/x/vip/privilege/my",
  1129. {
  1130. web_location
  1131. },
  1132. {
  1133. headers: {
  1134. Referer: "https://account.bilibili.com/account/big/myPackage",
  1135. Origin: "https://account.bilibili.com"
  1136. }
  1137. }
  1138. );
  1139. },
  1140. receivePrivilege: (type, platform = "web") => {
  1141. const bili_jct = useBiliStore().cookies.bili_jct;
  1142. return request.main.post(
  1143. "/x/vip/privilege/receive",
  1144. {
  1145. type,
  1146. platform,
  1147. csrf: bili_jct
  1148. },
  1149. {
  1150. headers: {
  1151. Referer: "https://account.bilibili.com/account/big/myPackage",
  1152. Origin: "https://account.bilibili.com"
  1153. }
  1154. }
  1155. );
  1156. },
  1157. addExperience: () => {
  1158. const biliStore = useBiliStore();
  1159. const mid = biliStore.BilibiliLive.UID;
  1160. const buvid = biliStore.cookies.buvid3;
  1161. const bili_jct = biliStore.cookies.bili_jct;
  1162. return request.main.post(
  1163. "/x/vip/experience/add",
  1164. {
  1165. mid,
  1166. buvid,
  1167. csrf: bili_jct
  1168. },
  1169. {
  1170. headers: {
  1171. Referer: "https://account.bilibili.com/big",
  1172. Origin: "https://account.bilibili.com"
  1173. }
  1174. }
  1175. );
  1176. }
  1177. }
  1178. },
  1179. vc: {
  1180. myGroups: (build = 0, mobi_app = "web") => {
  1181. return request.vc.get("/link_group/v1/member/my_groups", {
  1182. build,
  1183. mobi_app
  1184. });
  1185. },
  1186. signIn: (group_id, owner_id) => {
  1187. return request.vc.get("/link_setting/v1/link_setting/sign_in", {
  1188. group_id,
  1189. owner_id
  1190. });
  1191. }
  1192. }
  1193. };
  1194. class Logger {
  1195. constructor(title) {
  1196. __publicField(this, "NAME", "BLTH");
  1197. __publicField(this, "prefix_title_str");
  1198. __publicField(this, "title");
  1199. this.title = title;
  1200. this.prefix_title_str = title.split("_").join("][");
  1201. }
  1202. get prefix() {
  1203. return [
  1204. `%c${this.NAME}%c[${(/* @__PURE__ */ new Date()).toLocaleString()}]%c[${this.prefix_title_str}]%c:`,
  1205. "font-weight: bold; color: white; background-color: #23ade5; padding: 1px 4px; border-radius: 4px;",
  1206. "font-weight: bold; color: #0920e6;",
  1207. "font-weight: bold;",
  1208. ""
  1209. ];
  1210. }
  1211. log(...data) {
  1212. console.log(...this.prefix, ...data);
  1213. }
  1214. error(...data) {
  1215. console.error(...this.prefix, ...data);
  1216. }
  1217. warn(...data) {
  1218. console.warn(...this.prefix, ...data);
  1219. }
  1220. }
  1221. class BaseModule {
  1222. constructor(moduleName) {
  1223. /**
  1224. * 模块名称,在被导出时定义
  1225. *
  1226. * 输出控制台日志时会用到
  1227. */
  1228. __publicField(this, "moduleName");
  1229. /**
  1230. * 用于在控制台中输出日志信息
  1231. */
  1232. __publicField(this, "logger");
  1233. /**
  1234. * 储存所有模块信息的 Pinia Store
  1235. */
  1236. __publicField(this, "moduleStore", useModuleStore());
  1237. /**
  1238. * 推荐添加一个 config 属性来表示当前模块的配置项
  1239. *
  1240. * @example config: this.moduleStore.moduleConfig.DailyTasks.MainSiteTasks.login
  1241. */
  1242. __publicField(this, "config");
  1243. this.moduleName = moduleName;
  1244. this.logger = new Logger(this.moduleName);
  1245. }
  1246. /**
  1247. * 模块是否启用,默认通过 config.enabled 判断
  1248. *
  1249. * 如果没有 config.enabled 属性,则默认启用(比如默认模块)
  1250. */
  1251. isEnabled() {
  1252. var _a;
  1253. return ((_a = this.config) == null ? void 0 : _a.enabled) ?? true;
  1254. }
  1255. /**
  1256. * 如果需要在控制面板上显示模块状态,推荐添加一个 status setter 用来设置模块状态
  1257. *
  1258. * @example
  1259. * set status(s: moduleStatus) {
  1260. * this.moduleStore.moduleStatus.DailyTasks.MainSiteTasks.login = s
  1261. * }
  1262. */
  1263. set status(_s) {
  1264. throw new Error("Method not implemented.");
  1265. }
  1266. /**
  1267. * 运行模块
  1268. *
  1269. * 默认模块必须返回一个空的Promise,
  1270. * 其它模块若需要使用 await 可以返回一个空的Promise,否则无返回值
  1271. */
  1272. run() {
  1273. throw new Error("Method not implemented.");
  1274. }
  1275. }
  1276. /**
  1277. * 当脚本在多个页面上运行的时候,该模块是否要在每个页面上运行
  1278. *
  1279. * 默认false,即只在Main BLTH运行的页面上运行
  1280. *
  1281. * 该选项为 false 时如果要确保模块不会重复运行,还需将 onFrame 设置为 target 或 top
  1282. */
  1283. __publicField(BaseModule, "runOnMultiplePages", false);
  1284. /**
  1285. * 模块运行时机,默认 document-body
  1286. *
  1287. * `document-start`: 尽可能早,与脚本注入时机相同
  1288. *
  1289. * `document-head`: `document.head`刚刚出现后
  1290. *
  1291. * `document-body`: `document.body`刚刚出现后
  1292. *
  1293. * `document-end`: `document`的`DOMContentLoaded`事件触发后
  1294. *
  1295. * `window-load`: `window`的`load`事件触发后
  1296. *
  1297. * 默认模块的模块运行时机总是为 document-body
  1298. */
  1299. __publicField(BaseModule, "runAt", "document-body");
  1300. /**
  1301. * 模块运行的 frame,默认 target
  1302. *
  1303. * `all`: 所有符合脚本`@match`规则的 frame
  1304. *
  1305. * `target`: window.BilibiliLive 存在的那个 frame
  1306. *
  1307. * `top`: 顶层 frame (`window.top`)
  1308. *
  1309. * 如果设置为 target,那么至少要等到`document-body`时刻才能运行
  1310. *
  1311. * 默认模块运行的 frame 总是为 target
  1312. */
  1313. __publicField(BaseModule, "onFrame", "target");
  1314. /**
  1315. * 是否要等默认模块运行完了再运行,默认 true
  1316. *
  1317. * 如果设置为 true,那么就不能保证该模块被及时地执行
  1318. *
  1319. * 因为默认模块的运行时机总是 document-body,而且默认模块的运行时间是不确定的
  1320. */
  1321. __publicField(BaseModule, "runAfterDefault", true);
  1322. class ModuleError extends Error {
  1323. constructor(moduleName, message) {
  1324. super(message);
  1325. __publicField(this, "name", "ModuleError");
  1326. __publicField(this, "moduleName");
  1327. this.moduleName = moduleName;
  1328. }
  1329. }
  1330. class ModuleCriticalError extends ModuleError {
  1331. constructor(moduleName, message) {
  1332. super(moduleName, message);
  1333. __publicField(this, "name", "ModuleCriticalError");
  1334. __publicField(this, "moduleName");
  1335. this.moduleName = moduleName;
  1336. }
  1337. }
  1338. class UserInfo extends BaseModule {
  1339. /**
  1340. * 通过 BAPI.main.nav 获取用户基本信息
  1341. */
  1342. async getUserInfo() {
  1343. try {
  1344. const response = await BAPI.main.nav();
  1345. this.logger.log("BAPI.main.nav response", response);
  1346. if (response.code === 0) {
  1347. return response.data;
  1348. } else {
  1349. throw new Error(`响应 code 不为 0: ${response.message}`);
  1350. }
  1351. } catch (error) {
  1352. throw new ModuleCriticalError(this.moduleName, `获取用户信息出错: ${error.message}`);
  1353. }
  1354. }
  1355. async run() {
  1356. const biliStore = useBiliStore();
  1357. biliStore.userInfo = await this.getUserInfo();
  1358. setTimeout(
  1359. () => this.run().catch((reason) => this.logger.error(reason)),
  1360. delayToNextMoment(0, 4).ms
  1361. );
  1362. }
  1363. }
  1364. class DailyRewardInfo extends BaseModule {
  1365. /**
  1366. * 获取今日主站每日任务的完成情况
  1367. */
  1368. async getDailyRewardInfo() {
  1369. try {
  1370. const response = await BAPI.main.reward();
  1371. this.logger.log("BAPI.main.reward response", response);
  1372. if (response.code === 0) {
  1373. return response.data;
  1374. } else {
  1375. throw new Error(`响应 code 不为 0: ${response.message}`);
  1376. }
  1377. } catch (error) {
  1378. throw new ModuleError(this.moduleName, `获取主站每日任务完成情况出错: ${error.message}`);
  1379. }
  1380. }
  1381. async run() {
  1382. const biliStore = useBiliStore();
  1383. const mainSiteTasks = this.moduleStore.moduleConfig.DailyTasks.MainSiteTasks;
  1384. if (Object.values(mainSiteTasks).some(
  1385. (t) => t.enabled && !isTimestampToday(t._lastCompleteTime, 0, 4)
  1386. )) {
  1387. biliStore.dailyRewardInfo = await this.getDailyRewardInfo();
  1388. }
  1389. setTimeout(
  1390. () => this.run().catch((reason) => this.logger.error(reason)),
  1391. delayToNextMoment(0, 4).ms
  1392. );
  1393. }
  1394. }
  1395. class DynamicVideos extends BaseModule {
  1396. /**
  1397. * 从动态中获取一页视频的信息
  1398. *
  1399. * 每日观看视频,每日分享视频,每日投币都会用到
  1400. */
  1401. async getDynamicVideos() {
  1402. try {
  1403. const response = await BAPI.main.dynamicAll("video");
  1404. this.logger.log("BAPI.main.dynamicAll response", response);
  1405. if (response.code === 0) {
  1406. return response.data.items;
  1407. } else {
  1408. throw new Error(`响应 code 不为 0: ${response.message}`);
  1409. }
  1410. } catch (error) {
  1411. throw new ModuleError(this.moduleName, `获取主站每日任务完成情况出错: ${error.message}`);
  1412. }
  1413. }
  1414. async run() {
  1415. const biliStore = useBiliStore();
  1416. const mainSiteTasks = this.moduleStore.moduleConfig.DailyTasks.MainSiteTasks;
  1417. const taskValues = [mainSiteTasks.watch, mainSiteTasks.share, mainSiteTasks.coin];
  1418. if (taskValues.some((t) => t.enabled && !isTimestampToday(t._lastCompleteTime, 0, 4))) {
  1419. biliStore.dynamicVideos = await this.getDynamicVideos();
  1420. }
  1421. setTimeout(
  1422. () => this.run().catch((reason) => this.logger.error(reason)),
  1423. delayToNextMoment(0, 4).ms
  1424. );
  1425. }
  1426. }
  1427. class FansMetals extends BaseModule {
  1428. /**
  1429. * 获取粉丝勋章
  1430. *
  1431. * @param pages 获取的页数
  1432. */
  1433. async getFansMetals(pages = Infinity) {
  1434. const fansMetalList = [];
  1435. let total_page = 1;
  1436. try {
  1437. const firstPageResponse = await BAPI.live.fansMedalPanel(1);
  1438. this.logger.log("BAPI.live.fansMedalPanel(1) response", firstPageResponse);
  1439. if (firstPageResponse.code === 0) {
  1440. total_page = firstPageResponse.data.page_info.total_page;
  1441. fansMetalList.push(...firstPageResponse.data.special_list, ...firstPageResponse.data.list);
  1442. } else {
  1443. throw new Error(`获取粉丝勋章列表第1页失败: ${firstPageResponse.message}`);
  1444. }
  1445. for (let page = 2; page <= Math.min(total_page, pages); page++) {
  1446. const response = await BAPI.live.fansMedalPanel(page);
  1447. this.logger.log(`BAPI.live.fansMedalPanel(${page}) response`, response);
  1448. if (firstPageResponse.code === 0) {
  1449. fansMetalList.push(...response.data.list);
  1450. } else {
  1451. this.logger.error(
  1452. `获取粉丝勋章列表第${page}页失败,提前结束获取`,
  1453. firstPageResponse.message
  1454. );
  1455. return fansMetalList;
  1456. }
  1457. await sleep(_.random(300, 500));
  1458. }
  1459. return fansMetalList;
  1460. } catch (error) {
  1461. useBiliStore().fansMedalsStatus = "error";
  1462. throw new ModuleError(this.moduleName, `获取粉丝勋章列表出错: ${error.message}`);
  1463. }
  1464. }
  1465. async run() {
  1466. const biliStore = useBiliStore();
  1467. const emitter = useModuleStore().emitter;
  1468. emitter.off("Default_FansMedals");
  1469. emitter.on("Default_FansMedals", async () => {
  1470. biliStore.fansMedalsStatus = "loading";
  1471. biliStore.fansMedals = await this.getFansMetals(Infinity);
  1472. biliStore.fansMedalsStatus = "loaded";
  1473. });
  1474. const medalTasks = this.moduleStore.moduleConfig.DailyTasks.LiveTasks.medalTasks;
  1475. const taskValues = [medalTasks.light, medalTasks.watch];
  1476. if (taskValues.some((t) => t.enabled && !isTimestampToday(t._lastCompleteTime, 0, 4))) {
  1477. biliStore.fansMedalsStatus = "loading";
  1478. biliStore.fansMedals = await this.getFansMetals();
  1479. biliStore.fansMedalsStatus = "loaded";
  1480. }
  1481. setTimeout(
  1482. () => this.run().catch((reason) => this.logger.error(reason)),
  1483. delayToNextMoment(0, 4).ms
  1484. );
  1485. }
  1486. }
  1487. class Cookie {
  1488. /**
  1489. * 获取所有 cookies
  1490. */
  1491. static getAll() {
  1492. if (document.cookie === "") return {};
  1493. const cookies = document.cookie.split("; ");
  1494. const result = {};
  1495. for (const cookie of cookies) {
  1496. const [name, value] = cookie.split("=", 2);
  1497. result[decodeURIComponent(name)] = decodeURIComponent(value);
  1498. }
  1499. return result;
  1500. }
  1501. /**
  1502. * 获取指定名称的一个或多个 cookies
  1503. * @param names cookie 名称或 cookie 名称数组
  1504. * @param defaultValue 当 cookie 不存在时使用的默认值,默认 undefined
  1505. */
  1506. static get(names, defaultValue) {
  1507. const cookies = this.getAll();
  1508. if (Array.isArray(names)) {
  1509. const result = {};
  1510. for (const name of names) {
  1511. result[name] = cookies[name] ? cookies[name] : defaultValue;
  1512. }
  1513. return result;
  1514. } else {
  1515. return cookies[names] ? cookies[names] : defaultValue;
  1516. }
  1517. }
  1518. /**
  1519. * 获取一组 cookies,如果有 cookie 未获取到,会反复获取直到超时为止
  1520. *
  1521. * TODO: 等 cookieStore 普及后使用监听取代轮询
  1522. *
  1523. * @param names 要获取的 cookie 名称数组
  1524. * @param interval 获取间隔,默认 300 毫秒
  1525. * @param timeout 超时时间,若留空则永不超时
  1526. */
  1527. static getAsync(names, interval = 300, timeout) {
  1528. return new Promise((resolve2, reject2) => {
  1529. let remainCookieNames = [...names];
  1530. const cookies = this.get(remainCookieNames);
  1531. remainCookieNames = remainCookieNames.filter((r) => !cookies[r]);
  1532. if (remainCookieNames.length === 0) {
  1533. resolve2(cookies);
  1534. return;
  1535. }
  1536. let timeoutTimer;
  1537. const timer = setInterval(() => {
  1538. Object.assign(cookies, this.get(remainCookieNames));
  1539. remainCookieNames = remainCookieNames.filter((r) => !cookies[r]);
  1540. if (remainCookieNames.length === 0) {
  1541. if (timeout) clearTimeout(timeoutTimer);
  1542. clearInterval(timer);
  1543. resolve2(cookies);
  1544. }
  1545. }, interval);
  1546. if (timeout) {
  1547. timeoutTimer = setTimeout(() => {
  1548. clearInterval(timer);
  1549. reject2(new Error(`获取以下 cookie 超时:${remainCookieNames}`));
  1550. }, timeout);
  1551. }
  1552. });
  1553. }
  1554. }
  1555. class Cookies extends BaseModule {
  1556. /**
  1557. * 获取 Cookies
  1558. *
  1559. * bili_jct: 常作为参数 csrf 在请求中出现
  1560. * LIVE_BUVID: 如果用户以前从来没看过直播,此时可能为 null
  1561. * buvid3: 作为参数 buvid 在请求中出现,目前仅在主站 API 中使用
  1562. */
  1563. getCookies() {
  1564. return Cookie.getAsync(["bili_jct", "LIVE_BUVID", "buvid3"], 300, 1e4);
  1565. }
  1566. async run() {
  1567. try {
  1568. useBiliStore().cookies = await this.getCookies();
  1569. } catch (error) {
  1570. throw new ModuleCriticalError(this.moduleName, error.message);
  1571. }
  1572. }
  1573. }
  1574. class BilibiliLive extends BaseModule {
  1575. /**
  1576. * 获取 window.BilibiliLive
  1577. */
  1578. getBilibiliLive() {
  1579. this.logger.log("unsafeWindow.BilibiliLive", _unsafeWindow.BilibiliLive);
  1580. return new Promise((resolve2, reject2) => {
  1581. if (_unsafeWindow.BilibiliLive.UID !== 0) {
  1582. resolve2(_unsafeWindow.BilibiliLive);
  1583. return;
  1584. }
  1585. _unsafeWindow.BilibiliLive = new Proxy(_unsafeWindow.BilibiliLive, {
  1586. set(target, prop, value) {
  1587. target[prop] = value;
  1588. if (prop === "UID") {
  1589. _unsafeWindow.BilibiliLive = target;
  1590. resolve2(_unsafeWindow.BilibiliLive);
  1591. }
  1592. return true;
  1593. }
  1594. });
  1595. setTimeout(() => reject2(new Error("获取 BilibiliLive 超时")), 1e4);
  1596. });
  1597. }
  1598. async run() {
  1599. try {
  1600. useBiliStore().BilibiliLive = await this.getBilibiliLive();
  1601. } catch (error) {
  1602. throw new ModuleCriticalError(this.moduleName, error.message);
  1603. }
  1604. }
  1605. }
  1606. __publicField(BilibiliLive, "runOnMultiplePages", true);
  1607. const defaultModules = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  1608. __proto__: null,
  1609. Default_BilibiliLive: BilibiliLive,
  1610. Default_Cookies: Cookies,
  1611. Default_DailyRewardInfo: DailyRewardInfo,
  1612. Default_DynamicVideos: DynamicVideos,
  1613. Default_FansMetals: FansMetals,
  1614. Default_UserInfo: UserInfo
  1615. }, Symbol.toStringTag, { value: "Module" }));
  1616. class LoginTask extends BaseModule {
  1617. constructor() {
  1618. super(...arguments);
  1619. __publicField(this, "config", this.moduleStore.moduleConfig.DailyTasks.MainSiteTasks.login);
  1620. }
  1621. set status(s) {
  1622. this.moduleStore.moduleStatus.DailyTasks.MainSiteTasks.login = s;
  1623. }
  1624. async login() {
  1625. this.logger.log("每日登录(不可用)任务已完成");
  1626. this.config._lastCompleteTime = tsm();
  1627. this.status = "done";
  1628. return Promise.resolve();
  1629. }
  1630. async run() {
  1631. this.logger.log("每日登录(不可用)模块开始运行");
  1632. if (!isTimestampToday(this.config._lastCompleteTime)) {
  1633. const biliStore = useBiliStore();
  1634. if (!biliStore.dailyRewardInfo) {
  1635. this.logger.error("主站每日任务完成情况不存在,不执行每日登录(不可用)任务");
  1636. this.status = "error";
  1637. return;
  1638. }
  1639. this.status = "running";
  1640. if (!biliStore.dailyRewardInfo.login) {
  1641. await this.login();
  1642. } else {
  1643. this.config._lastCompleteTime = tsm();
  1644. this.status = "done";
  1645. }
  1646. } else {
  1647. if (isNowIn(0, 0, 0, 5)) {
  1648. this.logger.log("昨天的每日登录(不可用)任务已经完成过了,等到今天的00:05再执行");
  1649. } else {
  1650. this.logger.log("今天已经完成过每日登录(不可用)任务了");
  1651. this.status = "done";
  1652. }
  1653. }
  1654. const diff = delayToNextMoment();
  1655. setTimeout(() => this.run(), diff.ms);
  1656. this.logger.log("距离每日登录(不可用)模块下次运行时间:", diff.str);
  1657. }
  1658. }
  1659. let WatchTask$1 = class WatchTask extends BaseModule {
  1660. constructor() {
  1661. super(...arguments);
  1662. __publicField(this, "config", this.moduleStore.moduleConfig.DailyTasks.MainSiteTasks.watch);
  1663. }
  1664. set status(s) {
  1665. this.moduleStore.moduleStatus.DailyTasks.MainSiteTasks.watch = s;
  1666. }
  1667. /**
  1668. * 获取第一个视频的 aid
  1669. */
  1670. getAid() {
  1671. return Number(useBiliStore().dynamicVideos[0].modules.module_dynamic.major.archive.aid);
  1672. }
  1673. async watch(aid) {
  1674. try {
  1675. const response = await BAPI.main.videoHeartbeat(aid, _.random(1e9, 2e9));
  1676. this.logger.log(`BAPI.main.videoHeartbeat(${aid}) response`, response);
  1677. if (response.code === 0) {
  1678. this.logger.log("每日观看视频任务已完成");
  1679. this.config._lastCompleteTime = tsm();
  1680. this.status = "done";
  1681. } else {
  1682. this.logger.error("发送观看视频心跳失败", response.message);
  1683. this.status = "error";
  1684. }
  1685. } catch (err) {
  1686. this.logger.error("执行每日观看视频任务出错", err);
  1687. this.status = "error";
  1688. }
  1689. }
  1690. runCheck() {
  1691. const biliStore = useBiliStore();
  1692. if (!biliStore.dailyRewardInfo) {
  1693. this.logger.error("主站每日任务完成情况不存在,不执行每日观看视频任务");
  1694. this.status = "error";
  1695. return false;
  1696. }
  1697. if (!biliStore.dynamicVideos) {
  1698. this.logger.error("动态视频数据不存在,不执行每日观看视频任务");
  1699. this.status = "error";
  1700. return false;
  1701. }
  1702. return true;
  1703. }
  1704. async run() {
  1705. this.logger.log("每日观看视频模块开始运行");
  1706. if (!isTimestampToday(this.config._lastCompleteTime)) {
  1707. if (!this.runCheck()) {
  1708. return;
  1709. }
  1710. const biliStore = useBiliStore();
  1711. this.status = "running";
  1712. if (!biliStore.dailyRewardInfo.watch) {
  1713. const aid = this.getAid();
  1714. await this.watch(aid);
  1715. } else {
  1716. this.config._lastCompleteTime = tsm();
  1717. this.status = "done";
  1718. this.logger.log("每日观看视频任务已完成");
  1719. }
  1720. } else {
  1721. if (isNowIn(0, 0, 0, 5)) {
  1722. this.logger.log("昨天的每日观看视频任务已经完成过了,等到今天的00:05再执行");
  1723. } else {
  1724. this.logger.log("今天已经完成过每日观看视频任务了");
  1725. this.status = "done";
  1726. }
  1727. }
  1728. const diff = delayToNextMoment();
  1729. setTimeout(() => this.run(), diff.ms);
  1730. this.logger.log("距离每日观看视频模块下次运行时间:", diff.str);
  1731. }
  1732. };
  1733. class ShareTask extends BaseModule {
  1734. constructor() {
  1735. super(...arguments);
  1736. __publicField(this, "config", this.moduleStore.moduleConfig.DailyTasks.MainSiteTasks.share);
  1737. }
  1738. set status(s) {
  1739. this.moduleStore.moduleStatus.DailyTasks.MainSiteTasks.share = s;
  1740. }
  1741. getAid() {
  1742. const biliStore = useBiliStore();
  1743. return biliStore.dynamicVideos[0].modules.module_dynamic.major.archive.aid;
  1744. }
  1745. async share(aid) {
  1746. try {
  1747. const response = await BAPI.main.share(aid);
  1748. this.logger.log(`BAPI.main.share(${aid}) response`, response);
  1749. if (response.code === 0 || response.code === 71e3) {
  1750. this.logger.log("每日分享视频任务已完成");
  1751. this.config._lastCompleteTime = tsm();
  1752. this.status = "done";
  1753. } else {
  1754. this.logger.error("分享视频失败", response.message);
  1755. this.status = "error";
  1756. }
  1757. } catch (err) {
  1758. this.logger.error("执行每日分享视频任务出错", err);
  1759. this.status = "error";
  1760. }
  1761. }
  1762. runCheck() {
  1763. const biliStore = useBiliStore();
  1764. if (!biliStore.dailyRewardInfo) {
  1765. this.logger.error("主站每日任务完成情况不存在,不执行每日分享视频任务");
  1766. this.status = "error";
  1767. return false;
  1768. }
  1769. if (!biliStore.dynamicVideos) {
  1770. this.logger.error("动态视频数据不存在,不执行每日分享视频任务");
  1771. this.status = "error";
  1772. return false;
  1773. }
  1774. return true;
  1775. }
  1776. async run() {
  1777. this.logger.log("每日分享视频模块开始运行");
  1778. if (!isTimestampToday(this.config._lastCompleteTime)) {
  1779. if (!this.runCheck()) {
  1780. return;
  1781. }
  1782. const biliStore = useBiliStore();
  1783. this.status = "running";
  1784. if (!biliStore.dailyRewardInfo.share) {
  1785. const aid = this.getAid();
  1786. await this.share(aid);
  1787. } else {
  1788. this.config._lastCompleteTime = tsm();
  1789. this.status = "done";
  1790. this.logger.log("每日分享视频任务已完成");
  1791. }
  1792. } else {
  1793. if (isNowIn(0, 0, 0, 5)) {
  1794. this.logger.log("昨天的每日分享任务已经完成过了,等到今天的00:05再执行");
  1795. } else {
  1796. this.logger.log("今天已经完成过每日分享任务了");
  1797. this.status = "done";
  1798. }
  1799. }
  1800. const diff = delayToNextMoment();
  1801. setTimeout(() => this.run(), diff.ms);
  1802. this.logger.log("距离每日分享视频模块下次运行时间:", diff.str);
  1803. }
  1804. }
  1805. class CoinTask extends BaseModule {
  1806. constructor() {
  1807. super(...arguments);
  1808. __publicField(this, "config", this.moduleStore.moduleConfig.DailyTasks.MainSiteTasks.coin);
  1809. // 暂时先限制每个视频最多投一个币
  1810. // 因为转载视频只能投一个币,原创视频能投两个币
  1811. // 但是想查询视频是否为转载,我目前只知道一个 /x/web-interface/wbi/view
  1812. // 通过其响应的copyright字段(1原创,2转载)来判断
  1813. // 不过视频数量足够多,所以干脆直接限制每个视频最多投一个币
  1814. __publicField(this, "MAX_COIN", 1);
  1815. }
  1816. set status(s) {
  1817. this.moduleStore.moduleStatus.DailyTasks.MainSiteTasks.coin = s;
  1818. }
  1819. /**
  1820. * 获取动态视频的 aid 和 bvid
  1821. */
  1822. getDynamicVideoIds() {
  1823. const biliStore = useBiliStore();
  1824. return biliStore.dynamicVideos.map((item) => {
  1825. const archive = item.modules.module_dynamic.major.archive;
  1826. return {
  1827. aid: archive.aid,
  1828. bvid: archive.bvid
  1829. };
  1830. });
  1831. }
  1832. /**
  1833. * 获取一个视频的你的已投硬币数量
  1834. *
  1835. * @returns 你的已投硬币数
  1836. */
  1837. async getVideoCoinInfo(aid, bvid) {
  1838. try {
  1839. const response = await BAPI.main.videoRelation(aid, bvid);
  1840. this.logger.log(`BAPI.main.videoRelation(${aid}, ${bvid}) response`, response);
  1841. if (response.code === 0) {
  1842. return response.data.coin;
  1843. } else {
  1844. this.logger.error(`获取视频投币信息失败 aid = ${aid} bvid = ${bvid}`, response.message);
  1845. return 0;
  1846. }
  1847. } catch (error) {
  1848. this.logger.error(`获取视频投币信息出错 aid = ${aid} bvid = ${bvid}`, error);
  1849. return 0;
  1850. }
  1851. }
  1852. /**
  1853. * 给动态中的视频投币
  1854. * @param left_coin_num 还需要投的硬币数
  1855. */
  1856. async coinDynamicVideos(left_coin_num) {
  1857. const ids = this.getDynamicVideoIds();
  1858. for (const { aid, bvid } of ids) {
  1859. const coined_num = await this.getVideoCoinInfo(aid, bvid);
  1860. const allowed_coin_num = this.MAX_COIN - coined_num;
  1861. if (allowed_coin_num > 0) {
  1862. const coin_num = Math.min(allowed_coin_num, left_coin_num);
  1863. const result = await this.coin(aid, coin_num);
  1864. if (result === 0) {
  1865. left_coin_num -= coin_num;
  1866. if (left_coin_num === 0) {
  1867. this.logger.log("每日投币任务已完成");
  1868. this.config._lastCompleteTime = tsm();
  1869. this.status = "done";
  1870. break;
  1871. }
  1872. } else if (result === 1) {
  1873. this.logger.warn("硬币余额不足,每日投币任务终止");
  1874. this.status = "error";
  1875. break;
  1876. }
  1877. }
  1878. }
  1879. if (left_coin_num > 0) {
  1880. this.logger.warn("硬币余额不足,每日投币任务终止");
  1881. this.status = "error";
  1882. }
  1883. }
  1884. /**
  1885. * 投币
  1886. */
  1887. async coin(aid, num) {
  1888. try {
  1889. const response = await BAPI.main.coinAdd(aid, num);
  1890. this.logger.log(`BAPI.main.coinAdd(${aid}) response`, response);
  1891. if (response.code === 0) {
  1892. this.logger.log(`投币成功 视频aid = ${aid} 投币数量num = ${num}`);
  1893. return 0;
  1894. } else if (response.code === -104) {
  1895. this.logger.warn("硬币余额不足,每日投币任务终止");
  1896. return 1;
  1897. } else {
  1898. this.logger.error(`投币失败 视频aid = ${aid} 投币数量num = ${num}`, response.message);
  1899. return 2;
  1900. }
  1901. } catch (err) {
  1902. this.logger.error(`投币出错 视频aid = ${aid} 投币数量num = ${num}`, err);
  1903. return 3;
  1904. }
  1905. }
  1906. /**
  1907. * 运行前检查
  1908. */
  1909. runCheck() {
  1910. const biliStore = useBiliStore();
  1911. if (!biliStore.dailyRewardInfo) {
  1912. this.logger.error("主站每日任务完成情况不存在,不执行每日投币任务");
  1913. this.status = "error";
  1914. return false;
  1915. }
  1916. if (!biliStore.dynamicVideos) {
  1917. this.logger.error("动态视频数据不存在,不执行每日投币任务");
  1918. this.status = "error";
  1919. return false;
  1920. }
  1921. return true;
  1922. }
  1923. async run() {
  1924. this.logger.log("每日投币模块开始运行");
  1925. if (!isTimestampToday(this.config._lastCompleteTime)) {
  1926. if (!this.runCheck()) {
  1927. return;
  1928. }
  1929. const biliStore = useBiliStore();
  1930. this.status = "running";
  1931. const total_coined_num = biliStore.dailyRewardInfo.coins / 10;
  1932. if (total_coined_num < this.config.num) {
  1933. const left_coin_num = this.config.num - total_coined_num;
  1934. const money = biliStore.userInfo.money ?? 5;
  1935. if (left_coin_num > money) {
  1936. this.logger.log("硬币余额不足,不执行每日投币任务");
  1937. this.status = "done";
  1938. } else {
  1939. await this.coinDynamicVideos(left_coin_num);
  1940. }
  1941. } else {
  1942. this.config._lastCompleteTime = tsm();
  1943. this.status = "done";
  1944. this.logger.log("每日投币任务已完成");
  1945. }
  1946. } else {
  1947. if (isNowIn(0, 0, 0, 5)) {
  1948. this.logger.log("昨天的每日投币任务已经完成过了,等到今天的00:05再执行");
  1949. } else {
  1950. this.logger.log("今天已经完成过每日投币任务了");
  1951. this.status = "done";
  1952. }
  1953. }
  1954. const diff = delayToNextMoment();
  1955. setTimeout(() => this.run(), diff.ms);
  1956. this.logger.log("距离每日投币模块下次运行时间:", diff.str);
  1957. }
  1958. }
  1959. class SignTask extends BaseModule {
  1960. constructor() {
  1961. super(...arguments);
  1962. __publicField(this, "config", this.moduleStore.moduleConfig.DailyTasks.LiveTasks.sign);
  1963. }
  1964. set status(s) {
  1965. this.moduleStore.moduleStatus.DailyTasks.LiveTasks.sign = s;
  1966. }
  1967. async getSignInfo() {
  1968. try {
  1969. const response = await BAPI.live.getSignInfo();
  1970. this.logger.log("BAPI.live.getSignInfo response", response);
  1971. if (response.code === 0) {
  1972. return response.data;
  1973. } else {
  1974. this.logger.error("获取直播签到信息失败", response.message);
  1975. return null;
  1976. }
  1977. } catch (error) {
  1978. this.logger.error("获取直播签到信息出错", error);
  1979. return null;
  1980. }
  1981. }
  1982. async sign() {
  1983. try {
  1984. const response = await BAPI.live.doSign();
  1985. this.logger.log(`BAPI.live.doSign response`, response);
  1986. if (response.code === 0) {
  1987. this.logger.log("直播签到成功,获得奖励:", response.data.text);
  1988. this.config._lastCompleteTime = tsm();
  1989. this.status = "done";
  1990. this.logger.log("直播签到任务已完成");
  1991. } else {
  1992. this.logger.error("直播签到失败", response.message);
  1993. this.status = "error";
  1994. }
  1995. } catch (err) {
  1996. this.logger.error("执行直播签到任务出错", err);
  1997. this.status = "error";
  1998. }
  1999. }
  2000. async run() {
  2001. this.logger.log("直播签到模块开始运行");
  2002. if (!isTimestampToday(this.config._lastCompleteTime)) {
  2003. this.status = "running";
  2004. const signInfo = await this.getSignInfo();
  2005. if (signInfo) {
  2006. if (signInfo.status === 0) {
  2007. await this.sign();
  2008. } else {
  2009. this.config._lastCompleteTime = tsm();
  2010. this.status = "done";
  2011. }
  2012. } else {
  2013. await this.sign();
  2014. }
  2015. } else {
  2016. if (!isNowIn(0, 0, 0, 5)) {
  2017. this.logger.log("今天已经完成过直播签到任务了");
  2018. this.status = "done";
  2019. } else {
  2020. this.logger.log("昨天的直播签到任务已经完成过了,等到今天的00:05再执行");
  2021. }
  2022. }
  2023. const diff = delayToNextMoment();
  2024. setTimeout(() => this.run(), diff.ms);
  2025. this.logger.log("距离直播签到模块下次运行时间:", diff.str);
  2026. }
  2027. }
  2028. class MedalModule extends BaseModule {
  2029. /**
  2030. * 等待粉丝勋章数据获取完毕
  2031. *
  2032. * @returns 是否获取成功
  2033. */
  2034. waitForFansMedals() {
  2035. return new Promise((resolve2) => {
  2036. const { fansMedalsStatus } = pinia$1.storeToRefs(useBiliStore());
  2037. if (fansMedalsStatus.value === "loaded") {
  2038. resolve2(true);
  2039. } else {
  2040. const unwatch = vue.watch(fansMedalsStatus, (newValue) => {
  2041. if (newValue === "loaded") {
  2042. unwatch();
  2043. resolve2(true);
  2044. } else if (newValue === "error") {
  2045. unwatch();
  2046. resolve2(false);
  2047. }
  2048. });
  2049. }
  2050. });
  2051. }
  2052. }
  2053. class LightTask extends MedalModule {
  2054. constructor() {
  2055. super(...arguments);
  2056. __publicField(this, "medalTasksConfig", this.moduleStore.moduleConfig.DailyTasks.LiveTasks.medalTasks);
  2057. __publicField(this, "config", this.medalTasksConfig.light);
  2058. }
  2059. set status(s) {
  2060. this.moduleStore.moduleStatus.DailyTasks.LiveTasks.medalTasks.light = s;
  2061. }
  2062. /**
  2063. * 获取粉丝勋章,过滤不符合黑白名单要求和不需要点亮的粉丝勋章
  2064. * @returns 数组,数组中的每个元素都是数组:[房间号,主播uid]
  2065. */
  2066. getRoomidTargetidList() {
  2067. const filtered = useBiliStore().filteredFansMedals.filter(
  2068. (medal) => medal.medal.level < 20 && (this.medalTasksConfig.isWhiteList ? this.medalTasksConfig.roomidList.includes(medal.room_info.room_id) : !this.medalTasksConfig.roomidList.includes(medal.room_info.room_id)) && medal.medal.is_lighted === 0
  2069. ).map((medal) => [medal.room_info.room_id, medal.medal.target_id]);
  2070. if (this.medalTasksConfig.isWhiteList) {
  2071. const orderMap = arrayToMap(this.medalTasksConfig.roomidList);
  2072. return filtered.sort((a, b) => orderMap.get(a[0]) - orderMap.get(b[0]));
  2073. }
  2074. return filtered;
  2075. }
  2076. /**
  2077. * 点赞
  2078. * @param roomid 直播间号
  2079. * @param target_id 主播UID
  2080. * @param click_time 点赞次数
  2081. */
  2082. async like(roomid, target_id, click_time) {
  2083. try {
  2084. const response = await BAPI.live.likeReport(roomid, target_id, click_time);
  2085. this.logger.log(`BAPI.live.likeReport(${roomid}, ${target_id}, ${click_time})`, response);
  2086. if (response.code === 0) {
  2087. this.logger.log(
  2088. `点亮熄灭勋章-点赞 房间号 = ${roomid} 主播UID = ${target_id} 点赞次数 = ${click_time} 成功`
  2089. );
  2090. } else {
  2091. this.logger.error(
  2092. `点亮熄灭勋章-点赞 房间号 = ${roomid} 主播UID = ${target_id} 点赞次数 = ${click_time} 失败`,
  2093. response.message
  2094. );
  2095. }
  2096. } catch (error) {
  2097. this.logger.error(
  2098. `点亮熄灭勋章-点赞 房间号 = ${roomid} 主播UID = ${target_id} 点赞次数 = ${click_time} 出错`,
  2099. error
  2100. );
  2101. }
  2102. }
  2103. /**
  2104. * 发弹幕
  2105. * @param danmu 弹幕内容
  2106. * @param roomid 直播间号
  2107. */
  2108. async sendDanmu(danmu, roomid) {
  2109. try {
  2110. const response = await BAPI.live.sendMsg(danmu, roomid);
  2111. this.logger.log(`BAPI.live.sendMsg(${danmu}, ${roomid})`, response);
  2112. if (response.code === 0) {
  2113. if (response.msg === "k") {
  2114. this.logger.warn(
  2115. `点亮熄灭勋章-发送弹幕 在直播间 ${roomid} 发送弹幕 ${danmu} 异常,弹幕可能包含屏蔽词`
  2116. );
  2117. } else {
  2118. this.logger.log(`点亮熄灭勋章-发送弹幕 在直播间 ${roomid} 发送弹幕 ${danmu} 成功`);
  2119. }
  2120. } else {
  2121. this.logger.error(
  2122. `点亮熄灭勋章-发送弹幕 在直播间 ${roomid} 发送弹幕 ${danmu} 失败`,
  2123. response.message
  2124. );
  2125. }
  2126. } catch (error) {
  2127. this.logger.error(`点亮熄灭勋章-发送弹幕 在直播间 ${roomid} 发送弹幕 ${danmu} 出错`, error);
  2128. }
  2129. }
  2130. async run() {
  2131. this.logger.log("点亮熄灭勋章模块开始运行");
  2132. if (!isTimestampToday(this.config._lastCompleteTime)) {
  2133. if (!await this.waitForFansMedals()) {
  2134. this.logger.error("粉丝勋章数据不存在,不执行点亮熄灭勋章任务");
  2135. this.status = "error";
  2136. return;
  2137. }
  2138. this.status = "running";
  2139. const roomidTargetidList = this.getRoomidTargetidList();
  2140. if (roomidTargetidList.length > 0) {
  2141. for (let i = 0; i < roomidTargetidList.length; i++) {
  2142. const [roomid, target_id] = roomidTargetidList[i];
  2143. if (this.config.mode === "like") {
  2144. await this.like(roomid, target_id, _.random(31, 33));
  2145. } else {
  2146. await this.sendDanmu(this.config.danmuList[i % this.config.danmuList.length], roomid);
  2147. }
  2148. await sleep(_.random(3e3, 5e3));
  2149. }
  2150. }
  2151. this.config._lastCompleteTime = tsm();
  2152. this.status = "done";
  2153. this.logger.log("点亮熄灭勋章任务已完成");
  2154. } else {
  2155. if (isNowIn(0, 0, 0, 5)) {
  2156. this.logger.log("昨天的给点亮熄灭勋章任务已经完成过了,等到今天的00:05再执行");
  2157. } else {
  2158. this.logger.log("今天已经完成过点亮熄灭勋章任务了");
  2159. this.status = "done";
  2160. }
  2161. }
  2162. const diff = delayToNextMoment();
  2163. setTimeout(() => this.run(), diff.ms);
  2164. this.logger.log("距离点亮熄灭勋章模块下次运行时间:", diff.str);
  2165. }
  2166. }
  2167. class RoomHeart {
  2168. constructor(roomID, areaID, parentID, ruid, watchedSeconds) {
  2169. __publicField(this, "logger", new Logger("RoomHeart"));
  2170. __publicField(this, "config");
  2171. /** 今日当前直播间已观看时间(秒) */
  2172. __publicField(this, "watchedSeconds");
  2173. __publicField(this, "timer");
  2174. __publicField(this, "areaID");
  2175. __publicField(this, "parentID");
  2176. __publicField(this, "roomID");
  2177. /** 主播的 UID */
  2178. __publicField(this, "ruid");
  2179. __publicField(this, "seq", 0);
  2180. /** Cookie LIVE_BUVID */
  2181. __publicField(this, "buvid", useBiliStore().cookies.LIVE_BUVID);
  2182. __publicField(this, "uuid", uuid());
  2183. /** 计算签名和发送请求时均需要 JSON.stringify */
  2184. __publicField(this, "device", [this.buvid, this.uuid]);
  2185. /** 浏览器 user agent */
  2186. __publicField(this, "ua", navigator.userAgent);
  2187. __publicField(this, "heartBeatInterval");
  2188. __publicField(this, "secretKey");
  2189. __publicField(this, "secretRule");
  2190. /** ets */
  2191. __publicField(this, "timestamp");
  2192. this.roomID = roomID;
  2193. this.areaID = areaID;
  2194. this.parentID = parentID;
  2195. this.ruid = ruid;
  2196. this.watchedSeconds = watchedSeconds;
  2197. this.config = useModuleStore().moduleConfig.DailyTasks.LiveTasks.medalTasks.watch;
  2198. }
  2199. set status(s) {
  2200. useModuleStore().moduleStatus.DailyTasks.LiveTasks.medalTasks.watch = s;
  2201. }
  2202. /** 计算签名和发送请求时均需要 JSON.stringify */
  2203. get id() {
  2204. return [this.parentID, this.areaID, this.seq, this.roomID];
  2205. }
  2206. /** 更新当前直播间的观看任务进度 */
  2207. updateProgress() {
  2208. this.watchedSeconds += this.heartBeatInterval;
  2209. useModuleStore().moduleConfig.DailyTasks.LiveTasks.medalTasks.watch._watchingProgress[this.roomID] = this.watchedSeconds;
  2210. }
  2211. /**
  2212. * 开始心跳
  2213. */
  2214. start() {
  2215. if (!this.buvid) {
  2216. this.logger.error(`缺少buvid,无法为直播间 ${this.roomID} 执行观看直播任务,请尝试刷新页面`);
  2217. return Promise.resolve();
  2218. }
  2219. return this.E();
  2220. }
  2221. /**
  2222. * E心跳,开始时发送一次
  2223. */
  2224. async E() {
  2225. try {
  2226. const response = await BAPI.liveTrace.E(this.id, this.device, this.ruid);
  2227. this.logger.log(
  2228. `BAPI.liveTrace.E(${this.id}, ${this.device}, ${this.ruid}) response`,
  2229. response
  2230. );
  2231. if (response.code === 0) {
  2232. this.seq += 1;
  2233. ({
  2234. heartbeat_interval: this.heartBeatInterval,
  2235. secret_key: this.secretKey,
  2236. secret_rule: this.secretRule,
  2237. timestamp: this.timestamp
  2238. } = response.data);
  2239. await sleep(this.heartBeatInterval * 1e3);
  2240. return this.X();
  2241. } else {
  2242. this.logger.error(
  2243. `BAPI.liveTrace.E(${this.id}, ${this.device}, ${this.ruid}) 失败`,
  2244. response.message
  2245. );
  2246. }
  2247. } catch (error) {
  2248. this.logger.error(`BAPI.liveTrace.E(${this.id}, ${this.device}, ${this.ruid}) 出错`, error);
  2249. }
  2250. }
  2251. /**
  2252. * X心跳,E心跳过后都是X心跳
  2253. */
  2254. async X() {
  2255. if (isNowIn(23, 59, 0, 5)) {
  2256. this.logger.log(`即将或刚刚发生跨天,停止直播间 ${this.roomID} X心跳`);
  2257. return;
  2258. }
  2259. try {
  2260. const sypderData = {
  2261. id: JSON.stringify(this.id),
  2262. device: JSON.stringify(this.device),
  2263. ets: this.timestamp,
  2264. benchmark: this.secretKey,
  2265. time: this.heartBeatInterval,
  2266. ts: tsm(),
  2267. ua: this.ua
  2268. };
  2269. const s = this.spyder(JSON.stringify(sypderData), this.secretRule);
  2270. const response = await BAPI.liveTrace.X(
  2271. s,
  2272. this.id,
  2273. this.device,
  2274. this.ruid,
  2275. this.timestamp,
  2276. this.secretKey,
  2277. this.heartBeatInterval,
  2278. sypderData.ts
  2279. );
  2280. this.logger.log(
  2281. `BAPI.liveTrace.X(${s}, ${this.id}, ${this.device}, ${this.ruid}, ${this.timestamp}, ${this.secretKey}, ${this.heartBeatInterval}, ${sypderData.ts}) response`,
  2282. response
  2283. );
  2284. if (response.code === 0) {
  2285. this.seq += 1;
  2286. this.updateProgress();
  2287. if (this.watchedSeconds >= this.config.time * 60) {
  2288. clearTimeout(this.timer);
  2289. return;
  2290. }
  2291. ;
  2292. ({
  2293. heartbeat_interval: this.heartBeatInterval,
  2294. secret_key: this.secretKey,
  2295. secret_rule: this.secretRule,
  2296. timestamp: this.timestamp
  2297. } = response.data);
  2298. await sleep(this.heartBeatInterval * 1e3);
  2299. return this.X();
  2300. } else {
  2301. this.logger.error(
  2302. `BAPI.liveTrace.X(${s}, ${this.id}, ${this.device}, ${this.ruid}, ${this.timestamp}, ${this.secretKey}, ${this.heartBeatInterval}) 失败`,
  2303. response.message
  2304. );
  2305. }
  2306. } catch (error) {
  2307. this.logger.error(
  2308. `BAPI.liveTrace.X(s, ${this.id}, ${this.device}, ${this.ruid}, ${this.timestamp}, ${this.secretKey}, ${this.heartBeatInterval}) 出错`,
  2309. error
  2310. );
  2311. }
  2312. }
  2313. /**
  2314. * wasm 导出的 spyder 函数的 javascript 实现
  2315. * @param str 一个经过 JSON.stringify 的 json 字符串
  2316. * @param rule secret_rule 数组
  2317. * @returns s
  2318. */
  2319. spyder(str, rule) {
  2320. const data = JSON.parse(str);
  2321. const [parent_id, area_id, seq_id, room_id] = JSON.parse(data.id);
  2322. const [buvid, uuid2] = JSON.parse(data.device);
  2323. const key = data.benchmark;
  2324. const newData = {
  2325. platform: "web",
  2326. parent_id,
  2327. area_id,
  2328. seq_id,
  2329. room_id,
  2330. buvid,
  2331. uuid: uuid2,
  2332. ets: data.ets,
  2333. time: data.time,
  2334. ts: data.ts
  2335. };
  2336. let s = JSON.stringify(newData);
  2337. for (const r of rule) {
  2338. switch (r) {
  2339. case 0:
  2340. s = CryptoJS.HmacMD5(s, key).toString(CryptoJS.enc.Hex);
  2341. break;
  2342. case 1:
  2343. s = CryptoJS.HmacSHA1(s, key).toString(CryptoJS.enc.Hex);
  2344. break;
  2345. case 2:
  2346. s = CryptoJS.HmacSHA256(s, key).toString(CryptoJS.enc.Hex);
  2347. break;
  2348. case 3:
  2349. s = CryptoJS.HmacSHA224(s, key).toString(CryptoJS.enc.Hex);
  2350. break;
  2351. case 4:
  2352. s = CryptoJS.HmacSHA512(s, key).toString(CryptoJS.enc.Hex);
  2353. break;
  2354. case 5:
  2355. s = CryptoJS.HmacSHA384(s, key).toString(CryptoJS.enc.Hex);
  2356. break;
  2357. default:
  2358. s = CryptoJS.HmacMD5(s, key).toString(CryptoJS.enc.Hex);
  2359. }
  2360. }
  2361. return s;
  2362. }
  2363. }
  2364. class WatchTask2 extends MedalModule {
  2365. constructor() {
  2366. super(...arguments);
  2367. __publicField(this, "medalTasksConfig", this.moduleStore.moduleConfig.DailyTasks.LiveTasks.medalTasks);
  2368. __publicField(this, "config", this.medalTasksConfig.watch);
  2369. }
  2370. set status(s) {
  2371. this.moduleStore.moduleStatus.DailyTasks.LiveTasks.medalTasks.watch = s;
  2372. }
  2373. /**
  2374. * 获取粉丝勋章的房间号和主播uid,过滤等级大于等于20或不符合黑白名单要求的粉丝勋章
  2375. * @returns 数组,数组中的每个元素都是数组:[房间号,主播uid]
  2376. */
  2377. getRoomidUidList() {
  2378. const filtered = useBiliStore().filteredFansMedals.filter(
  2379. (medal) => medal.medal.level < 20 && (this.medalTasksConfig.isWhiteList ? this.medalTasksConfig.roomidList.includes(medal.room_info.room_id) : !this.medalTasksConfig.roomidList.includes(medal.room_info.room_id))
  2380. ).map((medal) => [medal.room_info.room_id, medal.medal.target_id]).slice(0, 199);
  2381. if (this.medalTasksConfig.isWhiteList) {
  2382. const orderMap = arrayToMap(this.medalTasksConfig.roomidList);
  2383. return filtered.sort((a, b) => orderMap.get(a[0]) - orderMap.get(b[0]));
  2384. }
  2385. return filtered;
  2386. }
  2387. /**
  2388. * 获取指定直播间的 area_id 和 parent_area_id
  2389. *
  2390. * 出错时返回 [-1, -1]
  2391. *
  2392. * @param roomid 房间号
  2393. * @returns [area_id, parent_area_id]
  2394. */
  2395. async getAreaInfo(roomid) {
  2396. try {
  2397. const response = await BAPI.live.getInfoByRoom(roomid);
  2398. this.logger.log(`BAPI.live.getInfoByRoom(${roomid}) response`, response);
  2399. if (response.code === 0) {
  2400. const room_info = response.data.room_info;
  2401. return [room_info.area_id, room_info.parent_area_id];
  2402. } else {
  2403. return [-1, -1];
  2404. }
  2405. } catch (error) {
  2406. this.logger.error(
  2407. `获取指定直播间的 area_id parent_area_id(roomid = ${roomid}) 出错`,
  2408. error
  2409. );
  2410. return [-1, -1];
  2411. }
  2412. }
  2413. async run() {
  2414. this.logger.log("观看直播模块开始运行");
  2415. if (!isTimestampToday(this.config._lastCompleteTime)) {
  2416. if (!await this.waitForFansMedals()) {
  2417. this.logger.error("粉丝勋章数据不存在,不执行观看直播任务");
  2418. this.status = "error";
  2419. return;
  2420. }
  2421. this.status = "running";
  2422. if (!isTimestampToday(this.config._lastWatchTime, 0, 0)) {
  2423. this.config._watchingProgress = {};
  2424. } else {
  2425. _.forOwn(this.config._watchingProgress, (value, key, object) => {
  2426. object[key] -= value % 300;
  2427. });
  2428. }
  2429. this.config._lastWatchTime = tsm();
  2430. const roomidUidList = this.getRoomidUidList();
  2431. if (roomidUidList.length > 0) {
  2432. let i;
  2433. for (i = 0; i < roomidUidList.length; i++) {
  2434. const [roomid, uid] = roomidUidList[i];
  2435. const [area_id, parent_area_id] = await this.getAreaInfo(roomid);
  2436. if (area_id > 0 && parent_area_id > 0) {
  2437. if (!this.config._watchingProgress[roomid] || this.config._watchingProgress[roomid] < this.config.time * 60) {
  2438. if (isNowIn(23, 55, 0, 5)) {
  2439. this.logger.log("即将或刚刚发生跨天,提早结束本轮观看直播任务");
  2440. break;
  2441. }
  2442. this.logger.log(`开始直播间${roomid}的观看直播任务`);
  2443. await new RoomHeart(
  2444. roomid,
  2445. area_id,
  2446. parent_area_id,
  2447. uid,
  2448. this.config._watchingProgress[roomid] ?? 0
  2449. ).start();
  2450. }
  2451. }
  2452. }
  2453. if (i === roomidUidList.length) {
  2454. this.config._lastCompleteTime = tsm();
  2455. this.logger.log("观看直播任务已完成");
  2456. this.status = "done";
  2457. }
  2458. } else {
  2459. this.status = "done";
  2460. this.config._lastCompleteTime = tsm();
  2461. }
  2462. } else {
  2463. if (isNowIn(0, 0, 0, 5)) {
  2464. this.logger.log("昨天的观看直播任务已经完成过了,等到今天的00:05再执行");
  2465. } else {
  2466. this.logger.log("今天已经完成过观看直播任务了");
  2467. this.status = "done";
  2468. }
  2469. }
  2470. const diff = delayToNextMoment();
  2471. setTimeout(() => this.run(), diff.ms);
  2472. this.logger.log("距离观看直播模块下次运行时间:", diff.str);
  2473. }
  2474. }
  2475. __publicField(WatchTask2, "runAt", "window-load");
  2476. class GroupSignTask extends BaseModule {
  2477. constructor() {
  2478. super(...arguments);
  2479. __publicField(this, "config", this.moduleStore.moduleConfig.DailyTasks.OtherTasks.groupSign);
  2480. }
  2481. set status(s) {
  2482. this.moduleStore.moduleStatus.DailyTasks.OtherTasks.groupSign = s;
  2483. }
  2484. /**
  2485. * 获取应援团 id 和拥有者 uid
  2486. * @returns 数组,每个元素都是数组:[应援团 id,拥有者 uid]
  2487. */
  2488. async getGroupidOwneruidList() {
  2489. try {
  2490. const response = await BAPI.vc.myGroups();
  2491. this.logger.log(`BAPI.vc.myGroups response`, response);
  2492. if (response.code === 0) {
  2493. return response.data.list.map((item) => [item.group_id, item.owner_uid]);
  2494. } else {
  2495. this.logger.error(`获取应援团信息失败`, response.message);
  2496. this.status = "error";
  2497. }
  2498. } catch (error) {
  2499. this.logger.error(`获取应援团信息出错`, error);
  2500. this.status = "error";
  2501. }
  2502. }
  2503. async sign(group_id, owner_uid) {
  2504. try {
  2505. const response = await BAPI.vc.signIn(group_id, owner_uid);
  2506. this.logger.log(`BAPI.vc.signIn(${group_id}, ${owner_uid}) response`, response);
  2507. if (response.code === 0) {
  2508. this.logger.log(
  2509. `应援团签到 应援团ID = ${group_id} 拥有者UID = ${owner_uid} 成功, 粉丝勋章亲密度+${response.data.add_num}`
  2510. );
  2511. } else {
  2512. this.logger.error(
  2513. `应援团签到 应援团ID = ${group_id} 拥有者UID = ${owner_uid} 失败`,
  2514. response.message
  2515. );
  2516. }
  2517. } catch (error) {
  2518. this.logger.error(`应援团签到 应援团ID = ${group_id} 拥有者UID = ${owner_uid} 出错`, error);
  2519. }
  2520. }
  2521. async run() {
  2522. this.logger.log("应援团签到模块开始运行");
  2523. if (!isTimestampToday(this.config._lastCompleteTime, 8, 5)) {
  2524. this.status = "running";
  2525. const idList = await this.getGroupidOwneruidList();
  2526. if (idList) {
  2527. for (const [group_id, owner_uid] of idList) {
  2528. await this.sign(group_id, owner_uid);
  2529. await sleep(2e3);
  2530. }
  2531. this.config._lastCompleteTime = tsm();
  2532. this.logger.log("应援团签到任务已完成");
  2533. this.status = "done";
  2534. }
  2535. } else {
  2536. if (!isNowIn(0, 0, 8, 5)) {
  2537. this.logger.log("今天已经完成过应援团签到任务了");
  2538. this.status = "done";
  2539. } else {
  2540. this.logger.log("昨天的应援团签到任务已经完成过了,等到今天早上八点零五分再次执行");
  2541. }
  2542. }
  2543. const diff = delayToNextMoment(8, 5);
  2544. setTimeout(() => this.run(), diff.ms);
  2545. this.logger.log("距离应援团签到模块下次运行时间:", diff.str);
  2546. }
  2547. }
  2548. class SilverToCoinTask extends BaseModule {
  2549. constructor() {
  2550. super(...arguments);
  2551. __publicField(this, "config", this.moduleStore.moduleConfig.DailyTasks.OtherTasks.silverToCoin);
  2552. }
  2553. set status(s) {
  2554. this.moduleStore.moduleStatus.DailyTasks.OtherTasks.silverToCoin = s;
  2555. }
  2556. async exchange() {
  2557. try {
  2558. const response = await BAPI.live.silver2coin();
  2559. this.logger.log(`BAPI.live.silver2coin response`, response);
  2560. if (response.code === 0) {
  2561. this.logger.log(`银瓜子换硬币已完成,获得硬币:`, response.data.coin);
  2562. this.config._lastCompleteTime = tsm();
  2563. this.status = "done";
  2564. } else if (response.code === 403) {
  2565. this.logger.log("每天最多只能用银瓜子兑换1个硬币");
  2566. this.config._lastCompleteTime = tsm();
  2567. this.status = "done";
  2568. } else {
  2569. this.logger.error("银瓜子换硬币失败", response.message);
  2570. this.status = "error";
  2571. }
  2572. } catch (err) {
  2573. this.logger.error("银瓜子换硬币出错", err);
  2574. this.status = "error";
  2575. }
  2576. }
  2577. run() {
  2578. this.logger.log("银瓜子换硬币模块开始运行");
  2579. if (!isTimestampToday(this.config._lastCompleteTime)) {
  2580. this.status = "running";
  2581. this.exchange();
  2582. } else {
  2583. if (isNowIn(0, 0, 0, 5)) {
  2584. this.logger.log("昨天的银瓜子换硬币任务已经完成过了,等到今天的00:05再执行");
  2585. } else {
  2586. this.logger.log("今天已经完成过银瓜子换硬币任务了");
  2587. this.status = "done";
  2588. }
  2589. }
  2590. const diff = delayToNextMoment();
  2591. setTimeout(() => this.run(), diff.ms);
  2592. this.logger.log("银瓜子换硬币模块下次运行时间:", diff.str);
  2593. }
  2594. }
  2595. class CoinToSilverTask extends BaseModule {
  2596. constructor() {
  2597. super(...arguments);
  2598. __publicField(this, "config", this.moduleStore.moduleConfig.DailyTasks.OtherTasks.coinToSilver);
  2599. }
  2600. set status(s) {
  2601. this.moduleStore.moduleStatus.DailyTasks.OtherTasks.coinToSilver = s;
  2602. }
  2603. async exchange() {
  2604. try {
  2605. const response = await BAPI.live.coin2silver(this.config.num);
  2606. this.logger.log(`BAPI.live.coin2silver{${this.config.num}} response`, response);
  2607. if (response.code === 0) {
  2608. this.logger.log("硬币换银瓜子已完成,获得银瓜子:", response.data.silver);
  2609. this.config._lastCompleteTime = tsm();
  2610. this.status = "done";
  2611. } else {
  2612. this.logger.error("硬币换银瓜子失败", response.message);
  2613. this.status = "error";
  2614. }
  2615. } catch (err) {
  2616. this.logger.error("硬币换银瓜子出错", err);
  2617. this.status = "error";
  2618. }
  2619. }
  2620. async run() {
  2621. this.logger.log("硬币换银瓜子模块开始运行");
  2622. if (!isTimestampToday(this.config._lastCompleteTime)) {
  2623. this.status = "running";
  2624. await this.exchange();
  2625. } else {
  2626. if (!isNowIn(0, 0, 0, 5)) {
  2627. this.logger.log("今天已经完成过硬币换银瓜子任务了");
  2628. this.status = "done";
  2629. } else {
  2630. this.logger.log("昨天的硬币换银瓜子任务已经完成过了,等到今天的00:05再执行");
  2631. }
  2632. }
  2633. const diff = delayToNextMoment();
  2634. setTimeout(() => this.run(), diff.ms);
  2635. this.logger.log("硬币换银瓜子模块下次运行时间:", diff.str);
  2636. }
  2637. }
  2638. class GetYearVipPrivilegeTask extends BaseModule {
  2639. constructor() {
  2640. super(...arguments);
  2641. __publicField(this, "config", this.moduleStore.moduleConfig.DailyTasks.OtherTasks.getYearVipPrivilege);
  2642. __publicField(this, "type2Name", {
  2643. 1: "年度专享B币赠送",
  2644. 2: "年度专享会员购优惠券",
  2645. 3: "年度专享漫画礼包 - 漫画福利券",
  2646. 4: "大会员专享会员购包邮券",
  2647. 5: "年度专享漫画礼包 - 漫画商城优惠券",
  2648. 6: "大会员专享会员体验卡",
  2649. 7: "大会员专享课堂优惠券",
  2650. 15: "年度专享会员购星光宝盒88折券",
  2651. 16: "大会员专享会员购10魔晶",
  2652. 17: "年度专享游戏优惠券"
  2653. });
  2654. }
  2655. set status(s) {
  2656. this.moduleStore.moduleStatus.DailyTasks.OtherTasks.getYearVipPrivilege = s;
  2657. }
  2658. /**
  2659. * 获取会员权益
  2660. * @returns 会员权益列表
  2661. */
  2662. async myPrivilege() {
  2663. try {
  2664. const response = await BAPI.main.vip.myPrivilege();
  2665. this.logger.log(`BAPI.main.vip.myPrivilege response`, response);
  2666. if (response.code === 0) {
  2667. return response.data.list;
  2668. } else {
  2669. this.logger.error(`获取年度大会员权益信息失败`, response.message);
  2670. this.status = "error";
  2671. }
  2672. } catch (error) {
  2673. this.logger.error(`获取年度大会员权益信息出错`, error);
  2674. this.status = "error";
  2675. }
  2676. }
  2677. /**
  2678. * 领取权益
  2679. * @param type 权益种类
  2680. */
  2681. async receivePrivilege(type) {
  2682. try {
  2683. const response = await BAPI.main.vip.receivePrivilege(type);
  2684. this.logger.log(`BAPI.main.vip.receivePrivilege(${type}) response`, response);
  2685. if (response.code === 0) {
  2686. this.logger.log(
  2687. `领取年度大会员权益(type = ${type}, ${this.type2Name[type] ?? "未知"})成功`
  2688. );
  2689. } else {
  2690. this.logger.error(
  2691. `领取年度大会员权益(type = ${type}, ${this.type2Name[type] ?? "未知"})失败`,
  2692. response.message
  2693. );
  2694. }
  2695. } catch (error) {
  2696. this.logger.error(
  2697. `领取年度大会员权益(type = ${type}, ${this.type2Name[type] ?? "未知"})出错`,
  2698. error
  2699. );
  2700. }
  2701. }
  2702. /**
  2703. * 领取专属等级加速包(10主站经验)
  2704. */
  2705. async addExperience() {
  2706. try {
  2707. const response = await BAPI.main.vip.addExperience();
  2708. this.logger.log(`BAPI.main.vip.addExperience response`, response);
  2709. if (response.code === 0) {
  2710. this.logger.log(`领取年度大会员权益(type = 9,专属等级加速包(10主站经验))成功`);
  2711. } else {
  2712. this.logger.error(
  2713. `领取年度大会员权益(type = 9,专属等级加速包(10主站经验))失败`,
  2714. response.message
  2715. );
  2716. }
  2717. } catch (error) {
  2718. this.logger.error(`领取年度大会员权益(type = 9,专属等级加速包(10主站经验))出错`, error);
  2719. }
  2720. }
  2721. /**
  2722. * 判断当前账号是否是年度大会员
  2723. */
  2724. isYearVip() {
  2725. const biliStore = useBiliStore();
  2726. const userInfo = biliStore.userInfo;
  2727. if (userInfo.vip.status === 1 && userInfo.vip.type === 2) {
  2728. return true;
  2729. } else {
  2730. this.logger.log("当前账号不是年度大会员,不领取权益");
  2731. return false;
  2732. }
  2733. }
  2734. async run() {
  2735. this.logger.log("领取年度大会员权益模块开始运行");
  2736. if (this.isYearVip()) {
  2737. if (ts() >= this.config._nextReceiveTime) {
  2738. this.status = "running";
  2739. const list = await this.myPrivilege();
  2740. if (list) {
  2741. for (const i of list) {
  2742. if (i.type === 8 || i.type === 14) {
  2743. continue;
  2744. }
  2745. if (i.state === 0) {
  2746. if (i.type === 9) {
  2747. await this.addExperience();
  2748. } else {
  2749. await this.receivePrivilege(i.type);
  2750. }
  2751. } else if (i.state === 1) {
  2752. this.logger.log(`该权益(type = ${i.type})已经领取过了`);
  2753. } else {
  2754. if (i.type === 9) {
  2755. const watchTaskConfig = this.moduleStore.moduleConfig.DailyTasks.MainSiteTasks.watch;
  2756. if (watchTaskConfig.enabled) {
  2757. this.logger.log("等待观看视频任务完成后再领取专属等级加速包(10主站经验)...");
  2758. vue.watch(
  2759. () => watchTaskConfig._lastCompleteTime,
  2760. () => sleep(3e3).then(() => this.addExperience()),
  2761. { once: true }
  2762. );
  2763. } else {
  2764. this.logger.warn(
  2765. "领取专属等级加速包(10主站经验)前需要观看任意一个视频,请打开【主站任务】中的【每日观看视频】,或是在运行脚本前手动观看"
  2766. );
  2767. }
  2768. }
  2769. }
  2770. await sleep(200);
  2771. }
  2772. this.status = "done";
  2773. this.config._nextReceiveTime = Math.min(...list.map((i) => i.period_end_unix));
  2774. }
  2775. }
  2776. const diff = this.config._nextReceiveTime - ts() + 3e5;
  2777. if (diff < 86400) {
  2778. this.logger.log(
  2779. "领取年度大会员权益模块下次运行时间:",
  2780. luxon.DateTime.fromSeconds(this.config._nextReceiveTime).toJSDate()
  2781. );
  2782. setTimeout(() => this.run(), diff * 1e3);
  2783. } else {
  2784. this.logger.log("距离下次领取年度大会员权益的时间超过一天,不计划下次运行");
  2785. }
  2786. }
  2787. }
  2788. }
  2789. const dq = document.querySelector.bind(document);
  2790. document.querySelectorAll.bind(document);
  2791. const dce = document.createElement.bind(document);
  2792. function waitForElement(parentElement, selector, timeout = 5e3) {
  2793. return new Promise((resolve2, reject2) => {
  2794. const element = parentElement.querySelector(selector);
  2795. if (element) {
  2796. resolve2(element);
  2797. return;
  2798. }
  2799. const observer = new MutationObserver(() => {
  2800. const element2 = parentElement.querySelector(selector);
  2801. if (element2) {
  2802. clearTimeout(timeoutId);
  2803. observer.disconnect();
  2804. resolve2(element2);
  2805. }
  2806. });
  2807. observer.observe(parentElement, {
  2808. childList: true,
  2809. subtree: true
  2810. });
  2811. const timeoutId = setTimeout(() => {
  2812. observer.disconnect();
  2813. reject2(new Error(`无法在${timeout}毫秒内找到${parentElement.localName}的子节点${selector}`));
  2814. }, timeout);
  2815. });
  2816. }
  2817. const isTargetFrame = () => document.head.innerHTML.includes("BilibiliLive");
  2818. const isSelfTopFrame = () => window.self === window.top;
  2819. const topFrameDocumentElement = () => {
  2820. var _a;
  2821. return (_a = window.top) == null ? void 0 : _a.document.documentElement;
  2822. };
  2823. class SwitchLiveStreamQuality extends BaseModule {
  2824. constructor() {
  2825. super(...arguments);
  2826. __publicField(this, "config", this.moduleStore.moduleConfig.EnhanceExperience.switchLiveStreamQuality);
  2827. }
  2828. async waitForPlayer() {
  2829. return new Promise((resolve2, reject2) => {
  2830. const topWindow = _unsafeWindow.top ? _unsafeWindow.top : _unsafeWindow;
  2831. const findPlayertimer = setInterval(() => {
  2832. if (topWindow.livePlayer && Object.hasOwn(topWindow.livePlayer, "switchQuality") && Object.hasOwn(topWindow.livePlayer, "getPlayerInfo")) {
  2833. clearInterval(findPlayertimer);
  2834. clearTimeout(timeoutTimer);
  2835. resolve2(topWindow.livePlayer);
  2836. }
  2837. }, 200);
  2838. const timeoutTimer = setTimeout(() => {
  2839. clearInterval(findPlayertimer);
  2840. clearTimeout(timeoutTimer);
  2841. reject2("等待播放器超时");
  2842. }, 1e4);
  2843. });
  2844. }
  2845. switchQuality(livePlayer) {
  2846. const playerInfo = livePlayer.getPlayerInfo();
  2847. if (playerInfo.liveStatus === 0) {
  2848. this.logger.log("当前直播间未开播,无需切换画质");
  2849. } else {
  2850. setTimeout(
  2851. () => {
  2852. const targetQuality = playerInfo.qualityCandidates.find(
  2853. ({ desc }) => desc === this.config.qualityDesc
  2854. );
  2855. if (targetQuality) {
  2856. if (playerInfo.quality !== targetQuality.qn) {
  2857. livePlayer.switchQuality(targetQuality.qn);
  2858. this.logger.log(`已将画质切换为${this.config.qualityDesc}`, targetQuality);
  2859. } else {
  2860. this.logger.log("当前画质已经是目标画质了,无需切换画质");
  2861. }
  2862. } else {
  2863. this.logger.log("当前直播不支持目标画质,保持默认画质");
  2864. }
  2865. },
  2866. // 这里针对特殊直播间和普通直播间设置了两套超时时间,特殊直播间超时时间更长
  2867. isSelfTopFrame() ? 2500 : 5e3
  2868. );
  2869. }
  2870. }
  2871. async run() {
  2872. this.logger.log("自动切换画质模块开始运行");
  2873. try {
  2874. const livePlayer = await this.waitForPlayer();
  2875. this.switchQuality(livePlayer);
  2876. } catch (e) {
  2877. this.logger.error("自动切换画质模块出错", e);
  2878. }
  2879. }
  2880. }
  2881. __publicField(SwitchLiveStreamQuality, "runOnMultiplePages", true);
  2882. __publicField(SwitchLiveStreamQuality, "runAt", "window-load");
  2883. __publicField(SwitchLiveStreamQuality, "runAfterDefault", false);
  2884. class BanP2P extends BaseModule {
  2885. constructor() {
  2886. super(...arguments);
  2887. __publicField(this, "config", this.moduleStore.moduleConfig.EnhanceExperience.banp2p);
  2888. }
  2889. banP2P() {
  2890. const RTClist = [
  2891. "RTCPeerConnection",
  2892. "mozRTCPeerConnection",
  2893. "webkitRTCPeerConnection"
  2894. ];
  2895. for (const i of RTClist) {
  2896. if (Object.hasOwn(_unsafeWindow, i)) {
  2897. Object.defineProperty(_unsafeWindow, i, {
  2898. value: class {
  2899. constructor() {
  2900. }
  2901. addEventListener() {
  2902. }
  2903. removeEventListener() {
  2904. }
  2905. createDataChannel() {
  2906. return { close: function() {
  2907. } };
  2908. }
  2909. createOffer() {
  2910. return Promise.resolve();
  2911. }
  2912. setLocalDescription() {
  2913. return Promise.resolve();
  2914. }
  2915. close() {
  2916. }
  2917. setRemoteDescription() {
  2918. return Promise.resolve();
  2919. }
  2920. createAnswer() {
  2921. }
  2922. },
  2923. enumerable: false,
  2924. writable: false,
  2925. configurable: false
  2926. });
  2927. }
  2928. }
  2929. }
  2930. run() {
  2931. this.logger.log("禁用P2P模块开始运行");
  2932. try {
  2933. this.banP2P();
  2934. } catch (e) {
  2935. this.logger.error("禁用P2P失败", e);
  2936. }
  2937. }
  2938. }
  2939. __publicField(BanP2P, "runOnMultiplePages", true);
  2940. __publicField(BanP2P, "runAt", "document-start");
  2941. __publicField(BanP2P, "onFrame", "all");
  2942. __publicField(BanP2P, "runAfterDefault", false);
  2943. var events = ["load", "loadend", "timeout", "error", "readystatechange", "abort"];
  2944. var OriginXhr = "__origin_xhr";
  2945. function configEvent(event, xhrProxy) {
  2946. var e = {};
  2947. for (var attr in event) e[attr] = event[attr];
  2948. e.target = e.currentTarget = xhrProxy;
  2949. return e;
  2950. }
  2951. function hook$1(proxy2, win) {
  2952. win = win || window;
  2953. var originXhr = win.XMLHttpRequest;
  2954. var hooking = true;
  2955. var HookXMLHttpRequest = function() {
  2956. var xhr = new originXhr();
  2957. for (var i = 0; i < events.length; ++i) {
  2958. var key = "on" + events[i];
  2959. if (xhr[key] === void 0) xhr[key] = null;
  2960. }
  2961. for (var attr in xhr) {
  2962. var type = "";
  2963. try {
  2964. type = typeof xhr[attr];
  2965. } catch (e) {
  2966. }
  2967. if (type === "function") {
  2968. this[attr] = hookFunction(attr);
  2969. } else if (attr !== OriginXhr) {
  2970. Object.defineProperty(this, attr, {
  2971. get: getterFactory(attr),
  2972. set: setterFactory(attr),
  2973. enumerable: true
  2974. });
  2975. }
  2976. }
  2977. var that = this;
  2978. xhr.getProxy = function() {
  2979. return that;
  2980. };
  2981. this[OriginXhr] = xhr;
  2982. };
  2983. HookXMLHttpRequest.prototype = originXhr.prototype;
  2984. HookXMLHttpRequest.prototype.constructor = HookXMLHttpRequest;
  2985. win.XMLHttpRequest = HookXMLHttpRequest;
  2986. Object.assign(win.XMLHttpRequest, { UNSENT: 0, OPENED: 1, HEADERS_RECEIVED: 2, LOADING: 3, DONE: 4 });
  2987. function getterFactory(attr) {
  2988. return function() {
  2989. var originValue = this[OriginXhr][attr];
  2990. if (hooking) {
  2991. var v = this.hasOwnProperty(attr + "_") ? this[attr + "_"] : originValue;
  2992. var attrGetterHook = (proxy2[attr] || {})["getter"];
  2993. return attrGetterHook && attrGetterHook(v, this) || v;
  2994. } else {
  2995. return originValue;
  2996. }
  2997. };
  2998. }
  2999. function setterFactory(attr) {
  3000. return function(v) {
  3001. var xhr = this[OriginXhr];
  3002. if (hooking) {
  3003. var that = this;
  3004. var hook2 = proxy2[attr];
  3005. if (attr.substring(0, 2) === "on") {
  3006. that[attr + "_"] = v;
  3007. xhr[attr] = function(e) {
  3008. e = configEvent(e, that);
  3009. var ret = proxy2[attr] && proxy2[attr].call(that, xhr, e);
  3010. ret || v.call(that, e);
  3011. };
  3012. } else {
  3013. var attrSetterHook = (hook2 || {})["setter"];
  3014. v = attrSetterHook && attrSetterHook(v, that) || v;
  3015. this[attr + "_"] = v;
  3016. try {
  3017. xhr[attr] = v;
  3018. } catch (e) {
  3019. }
  3020. }
  3021. } else {
  3022. xhr[attr] = v;
  3023. }
  3024. };
  3025. }
  3026. function hookFunction(fun) {
  3027. return function() {
  3028. var args = [].slice.call(arguments);
  3029. if (proxy2[fun] && hooking) {
  3030. var ret = proxy2[fun].call(this, args, this[OriginXhr]);
  3031. if (ret) return ret;
  3032. }
  3033. return this[OriginXhr][fun].apply(this[OriginXhr], args);
  3034. };
  3035. }
  3036. function unHook() {
  3037. hooking = false;
  3038. if (win.XMLHttpRequest === HookXMLHttpRequest) {
  3039. win.XMLHttpRequest = originXhr;
  3040. HookXMLHttpRequest.prototype.constructor = originXhr;
  3041. originXhr = void 0;
  3042. }
  3043. }
  3044. return { originXhr, unHook };
  3045. }
  3046. var eventLoad = events[0], eventLoadEnd = events[1], eventTimeout = events[2], eventError = events[3], eventReadyStateChange = events[4], eventAbort = events[5];
  3047. var prototype = "prototype";
  3048. function proxy(proxy2, win) {
  3049. win = win || window;
  3050. return proxyAjax(proxy2, win);
  3051. }
  3052. function trim(str) {
  3053. return str.replace(/^\s+|\s+$/g, "");
  3054. }
  3055. function getEventTarget(xhr) {
  3056. return xhr.watcher || (xhr.watcher = document.createElement("a"));
  3057. }
  3058. function triggerListener(xhr, name) {
  3059. var xhrProxy = xhr.getProxy();
  3060. var callback = "on" + name + "_";
  3061. var event = configEvent({ type: name }, xhrProxy);
  3062. xhrProxy[callback] && xhrProxy[callback](event);
  3063. var evt;
  3064. if (typeof Event === "function") {
  3065. evt = new Event(name, { bubbles: false });
  3066. } else {
  3067. evt = document.createEvent("Event");
  3068. evt.initEvent(name, false, true);
  3069. }
  3070. getEventTarget(xhr).dispatchEvent(evt);
  3071. }
  3072. function Handler(xhr) {
  3073. this.xhr = xhr;
  3074. this.xhrProxy = xhr.getProxy();
  3075. }
  3076. Handler[prototype] = /* @__PURE__ */ Object.create({
  3077. resolve: function resolve(response) {
  3078. var xhrProxy = this.xhrProxy;
  3079. var xhr = this.xhr;
  3080. xhrProxy.readyState = 4;
  3081. xhr.resHeader = response.headers;
  3082. xhrProxy.response = xhrProxy.responseText = response.response;
  3083. xhrProxy.statusText = response.statusText;
  3084. xhrProxy.status = response.status;
  3085. triggerListener(xhr, eventReadyStateChange);
  3086. triggerListener(xhr, eventLoad);
  3087. triggerListener(xhr, eventLoadEnd);
  3088. },
  3089. reject: function reject(error) {
  3090. this.xhrProxy.status = 0;
  3091. triggerListener(this.xhr, error.type);
  3092. triggerListener(this.xhr, eventLoadEnd);
  3093. }
  3094. });
  3095. function makeHandler(next) {
  3096. function sub(xhr) {
  3097. Handler.call(this, xhr);
  3098. }
  3099. sub[prototype] = Object.create(Handler[prototype]);
  3100. sub[prototype].next = next;
  3101. return sub;
  3102. }
  3103. var RequestHandler$1 = makeHandler(function(rq) {
  3104. var xhr = this.xhr;
  3105. rq = rq || xhr.config;
  3106. xhr.withCredentials = rq.withCredentials;
  3107. xhr.open(rq.method, rq.url, rq.async !== false, rq.user, rq.password);
  3108. for (var key in rq.headers) {
  3109. xhr.setRequestHeader(key, rq.headers[key]);
  3110. }
  3111. xhr.send(rq.body);
  3112. });
  3113. var ResponseHandler$1 = makeHandler(function(response) {
  3114. this.resolve(response);
  3115. });
  3116. var ErrorHandler = makeHandler(function(error) {
  3117. this.reject(error);
  3118. });
  3119. function proxyAjax(proxy2, win) {
  3120. var onRequest = proxy2.onRequest, onResponse = proxy2.onResponse, onError = proxy2.onError;
  3121. function getResponseData(xhrProxy) {
  3122. var responseType = xhrProxy.responseType;
  3123. if (!responseType || responseType === "text") {
  3124. return xhrProxy.responseText;
  3125. }
  3126. var response = xhrProxy.response;
  3127. if (responseType === "json" && !response) {
  3128. try {
  3129. return JSON.parse(xhrProxy.responseText);
  3130. } catch (e) {
  3131. console.warn(e);
  3132. }
  3133. }
  3134. return response;
  3135. }
  3136. function handleResponse(xhr, xhrProxy) {
  3137. var handler = new ResponseHandler$1(xhr);
  3138. var ret = {
  3139. response: getResponseData(xhrProxy),
  3140. status: xhrProxy.status,
  3141. statusText: xhrProxy.statusText,
  3142. config: xhr.config,
  3143. headers: xhr.resHeader || xhr.getAllResponseHeaders().split("\r\n").reduce(function(ob, str) {
  3144. if (str === "") return ob;
  3145. var m = str.split(":");
  3146. ob[m.shift()] = trim(m.join(":"));
  3147. return ob;
  3148. }, {})
  3149. };
  3150. if (!onResponse) return handler.resolve(ret);
  3151. onResponse(ret, handler);
  3152. }
  3153. function onerror(xhr, xhrProxy, error, errorType) {
  3154. var handler = new ErrorHandler(xhr);
  3155. error = { config: xhr.config, error, type: errorType };
  3156. if (onError) {
  3157. onError(error, handler);
  3158. } else {
  3159. handler.next(error);
  3160. }
  3161. }
  3162. function preventXhrProxyCallback() {
  3163. return true;
  3164. }
  3165. function errorCallback(errorType) {
  3166. return function(xhr, e) {
  3167. onerror(xhr, this, e, errorType);
  3168. return true;
  3169. };
  3170. }
  3171. function stateChangeCallback(xhr, xhrProxy) {
  3172. if (xhr.readyState === 4 && xhr.status !== 0) {
  3173. handleResponse(xhr, xhrProxy);
  3174. } else if (xhr.readyState !== 4) {
  3175. triggerListener(xhr, eventReadyStateChange);
  3176. }
  3177. return true;
  3178. }
  3179. var { originXhr, unHook } = hook$1({
  3180. onload: preventXhrProxyCallback,
  3181. onloadend: preventXhrProxyCallback,
  3182. onerror: errorCallback(eventError),
  3183. ontimeout: errorCallback(eventTimeout),
  3184. onabort: errorCallback(eventAbort),
  3185. onreadystatechange: function(xhr) {
  3186. return stateChangeCallback(xhr, this);
  3187. },
  3188. open: function open(args, xhr) {
  3189. var _this = this;
  3190. var config = xhr.config = { headers: {} };
  3191. config.method = args[0];
  3192. config.url = args[1];
  3193. config.async = args[2];
  3194. config.user = args[3];
  3195. config.password = args[4];
  3196. config.xhr = xhr;
  3197. var evName = "on" + eventReadyStateChange;
  3198. if (!xhr[evName]) {
  3199. xhr[evName] = function() {
  3200. return stateChangeCallback(xhr, _this);
  3201. };
  3202. }
  3203. if (onRequest) return true;
  3204. },
  3205. send: function(args, xhr) {
  3206. var config = xhr.config;
  3207. config.withCredentials = xhr.withCredentials;
  3208. config.body = args[0];
  3209. if (onRequest) {
  3210. var req = function() {
  3211. onRequest(config, new RequestHandler$1(xhr));
  3212. };
  3213. config.async === false ? req() : setTimeout(req);
  3214. return true;
  3215. }
  3216. },
  3217. setRequestHeader: function(args, xhr) {
  3218. xhr.config.headers[args[0].toLowerCase()] = args[1];
  3219. if (onRequest) return true;
  3220. },
  3221. addEventListener: function(args, xhr) {
  3222. var _this = this;
  3223. if (events.indexOf(args[0]) !== -1) {
  3224. var handler = args[1];
  3225. getEventTarget(xhr).addEventListener(args[0], function(e) {
  3226. var event = configEvent(e, _this);
  3227. event.type = args[0];
  3228. event.isTrusted = true;
  3229. handler.call(_this, event);
  3230. });
  3231. return true;
  3232. }
  3233. },
  3234. getAllResponseHeaders: function(_2, xhr) {
  3235. var headers = xhr.resHeader;
  3236. if (headers) {
  3237. var header = "";
  3238. for (var key in headers) {
  3239. header += key + ": " + headers[key] + "\r\n";
  3240. }
  3241. return header;
  3242. }
  3243. },
  3244. getResponseHeader: function(args, xhr) {
  3245. var headers = xhr.resHeader;
  3246. if (headers) {
  3247. return headers[(args[0] || "").toLowerCase()];
  3248. }
  3249. }
  3250. }, win);
  3251. return {
  3252. originXhr,
  3253. unProxy: unHook
  3254. };
  3255. }
  3256. const _fetch = window.fetch;
  3257. class RequestHandler {
  3258. constructor() {
  3259. __publicField(this, "_resolve");
  3260. __publicField(this, "_error");
  3261. __publicField(this, "_next", false);
  3262. __publicField(this, "_input");
  3263. __publicField(this, "_init");
  3264. }
  3265. resolve(response) {
  3266. this._resolve = Promise.resolve(response);
  3267. }
  3268. error(error) {
  3269. this._error = error;
  3270. }
  3271. next(config) {
  3272. this._next = true;
  3273. this._input = config.input;
  3274. this._init = config.init;
  3275. }
  3276. }
  3277. class ResponseHandler {
  3278. constructor() {
  3279. __publicField(this, "_resolve");
  3280. __publicField(this, "_error");
  3281. __publicField(this, "_next", false);
  3282. __publicField(this, "_response");
  3283. }
  3284. resolve(response) {
  3285. this._resolve = Promise.resolve(response);
  3286. }
  3287. error(error) {
  3288. this._error = error;
  3289. }
  3290. next(response) {
  3291. this._next = true;
  3292. this._response = response;
  3293. }
  3294. }
  3295. let isHooked = false;
  3296. let onRequestHandlers = [];
  3297. let onResponseHandlers = [];
  3298. const hook = (win) => {
  3299. win.fetch = async (input, init) => {
  3300. for (const handler of onRequestHandlers) {
  3301. const requestHandler = new RequestHandler();
  3302. await handler.apply(_unsafeWindow, [{ input, init }, requestHandler]);
  3303. if (requestHandler._resolve) {
  3304. return requestHandler._resolve;
  3305. }
  3306. if (requestHandler._error) {
  3307. throw requestHandler._error;
  3308. }
  3309. if (!requestHandler._next) {
  3310. break;
  3311. }
  3312. input = requestHandler._input;
  3313. init = requestHandler._init;
  3314. }
  3315. let response = await _fetch.apply(_unsafeWindow, [input, init]);
  3316. for (const handler of onResponseHandlers) {
  3317. const responseHandler = new ResponseHandler();
  3318. await handler.apply(_unsafeWindow, [response, responseHandler]);
  3319. if (responseHandler._resolve) {
  3320. return responseHandler._resolve;
  3321. }
  3322. if (responseHandler._error) {
  3323. throw responseHandler._error;
  3324. }
  3325. if (!responseHandler._next) {
  3326. break;
  3327. }
  3328. response = responseHandler._response;
  3329. }
  3330. return response;
  3331. };
  3332. };
  3333. const fproxy = (proxy2, win = _unsafeWindow) => {
  3334. if (proxy2.onRequest) {
  3335. onRequestHandlers.push(proxy2.onRequest);
  3336. }
  3337. if (proxy2.onResponse) {
  3338. onResponseHandlers.push(proxy2.onResponse);
  3339. }
  3340. if (!isHooked) {
  3341. hook(win);
  3342. isHooked = true;
  3343. }
  3344. return {
  3345. unProxy: () => {
  3346. if (proxy2.onRequest) {
  3347. onRequestHandlers.splice(
  3348. onRequestHandlers.findIndex((handler) => handler === proxy2.onRequest),
  3349. 1
  3350. );
  3351. }
  3352. if (proxy2.onResponse) {
  3353. onResponseHandlers.splice(
  3354. onResponseHandlers.findIndex((handler) => handler === proxy2.onResponse),
  3355. 1
  3356. );
  3357. }
  3358. },
  3359. unHook: () => {
  3360. win.fetch = _fetch;
  3361. onRequestHandlers = [];
  3362. onResponseHandlers = [];
  3363. },
  3364. originFetch: _fetch
  3365. };
  3366. };
  3367. const _NoReport = class _NoReport extends BaseModule {
  3368. constructor() {
  3369. super(...arguments);
  3370. __publicField(this, "config", this.moduleStore.moduleConfig.EnhanceExperience.noReport);
  3371. }
  3372. /**
  3373. * 判断是否是需要拦截的 URL
  3374. * @param url 需要判断的 URL
  3375. */
  3376. static isTargetURL(url) {
  3377. return url.includes("//data.bilibili.com") || url.includes("//data.bilivideo.com");
  3378. }
  3379. /**
  3380. * 劫持一些能减少日志上报的方法
  3381. * @param win window
  3382. */
  3383. hookProperties(win) {
  3384. Object.defineProperty(win.navigator, "sendBeacon", {
  3385. value: () => {
  3386. return true;
  3387. }
  3388. });
  3389. Object.defineProperties(win, {
  3390. reportObserver: {
  3391. get() {
  3392. return {
  3393. reportCustomData: function() {
  3394. }
  3395. };
  3396. },
  3397. set() {
  3398. }
  3399. },
  3400. reportConfig: {
  3401. get() {
  3402. return {};
  3403. },
  3404. set() {
  3405. }
  3406. }
  3407. });
  3408. }
  3409. /**
  3410. * 劫持 XHR 和 fetch 请求
  3411. */
  3412. ajaxHook() {
  3413. const ajaxHookProxyConfig = {
  3414. onRequest: (config, handler) => {
  3415. if (_NoReport.isTargetURL(config.url)) {
  3416. handler.resolve({
  3417. config,
  3418. status: 200,
  3419. headers: {
  3420. "Content-Type": "text/plain; charset=utf-8"
  3421. },
  3422. response: "ok"
  3423. });
  3424. } else {
  3425. handler.next(config);
  3426. }
  3427. }
  3428. };
  3429. const fetchHookConfig = {
  3430. onRequest(config, handler) {
  3431. const url = getUrlFromFetchInput(config.input);
  3432. if (_NoReport.isTargetURL(url)) {
  3433. handler.resolve(new Response("ok"));
  3434. } else {
  3435. handler.next(config);
  3436. }
  3437. },
  3438. onResponse(response, handler) {
  3439. handler.next(response);
  3440. }
  3441. };
  3442. proxy(ajaxHookProxyConfig, _unsafeWindow);
  3443. fproxy(fetchHookConfig, _unsafeWindow);
  3444. }
  3445. run() {
  3446. this.logger.log("拦截日志数据上报模块开始运行");
  3447. try {
  3448. this.hookProperties(_unsafeWindow);
  3449. this.ajaxHook();
  3450. } catch (e) {
  3451. this.logger.error("拦截日志数据上报失败", e);
  3452. }
  3453. }
  3454. };
  3455. __publicField(_NoReport, "runOnMultiplePages", true);
  3456. __publicField(_NoReport, "runAt", "document-start");
  3457. __publicField(_NoReport, "onFrame", "all");
  3458. __publicField(_NoReport, "runAfterDefault", false);
  3459. let NoReport = _NoReport;
  3460. class NoSleep extends BaseModule {
  3461. constructor() {
  3462. super(...arguments);
  3463. __publicField(this, "config", this.moduleStore.moduleConfig.EnhanceExperience.noSleep);
  3464. }
  3465. run() {
  3466. this.logger.log("屏蔽挂机检测模块开始运行");
  3467. setInterval(() => {
  3468. document.dispatchEvent(new MouseEvent("mousemove"));
  3469. }, 3e5);
  3470. }
  3471. }
  3472. __publicField(NoSleep, "runOnMultiplePages", true);
  3473. __publicField(NoSleep, "runAt", "window-load");
  3474. __publicField(NoSleep, "runAfterDefault", false);
  3475. class Invisibility extends BaseModule {
  3476. constructor() {
  3477. super(...arguments);
  3478. __publicField(this, "config", this.moduleStore.moduleConfig.EnhanceExperience.invisibility);
  3479. }
  3480. run() {
  3481. this.logger.log("隐身入场模块开始运行");
  3482. proxy(
  3483. {
  3484. onRequest: (config, handler) => {
  3485. if (config.url.includes("//api.live.bilibili.com/xlive/web-room/v1/index/getInfoByUser")) {
  3486. config.url = config.url.replace("not_mock_enter_effect=0", "not_mock_enter_effect=1");
  3487. }
  3488. handler.next(config);
  3489. }
  3490. },
  3491. _unsafeWindow
  3492. );
  3493. }
  3494. }
  3495. __publicField(Invisibility, "runOnMultiplePages", true);
  3496. __publicField(Invisibility, "runAt", "document-start");
  3497. __publicField(Invisibility, "runAfterDefault", false);
  3498. __publicField(Invisibility, "onFrame", "all");
  3499. class RemovePKBox extends BaseModule {
  3500. constructor() {
  3501. super(...arguments);
  3502. __publicField(this, "config", this.moduleStore.moduleConfig.RemoveElement.removePKBox);
  3503. }
  3504. removePKNode() {
  3505. _GM_addStyle("#awesome-pk-vm { display: none !important }");
  3506. }
  3507. removePKToast() {
  3508. const blackWordList = ["主播即将结束PK", "连线断开中"];
  3509. const pkOB = new MutationObserver((mutationsList) => {
  3510. for (const mutation of mutationsList) {
  3511. mutation.addedNodes.forEach((addedNode) => {
  3512. if (addedNode instanceof HTMLElement && addedNode.classList.contains("link-toast") && blackWordList.some((word) => {
  3513. var _a;
  3514. return (_a = addedNode.textContent) == null ? void 0 : _a.includes(word);
  3515. })) {
  3516. addedNode.style.display = "none";
  3517. }
  3518. });
  3519. }
  3520. });
  3521. pkOB.observe(document.body, { childList: true });
  3522. }
  3523. async run() {
  3524. this.logger.log("移除大乱斗元素模块开始运行");
  3525. this.removePKNode();
  3526. this.removePKToast();
  3527. }
  3528. }
  3529. __publicField(RemovePKBox, "runOnMultiplePages", true);
  3530. class RemoveLiveWaterMark extends BaseModule {
  3531. constructor() {
  3532. super(...arguments);
  3533. __publicField(this, "config", this.moduleStore.moduleConfig.RemoveElement.removeLiveWaterMark);
  3534. }
  3535. async run() {
  3536. this.logger.log("移除直播间水印模块开始运行");
  3537. _GM_addStyle(".web-player-icon-roomStatus { display: none !important }");
  3538. }
  3539. }
  3540. __publicField(RemoveLiveWaterMark, "runOnMultiplePages", true);
  3541. class RemoveShopPopover extends BaseModule {
  3542. constructor() {
  3543. super(...arguments);
  3544. __publicField(this, "config", this.moduleStore.moduleConfig.RemoveElement.removeShopPopover);
  3545. }
  3546. async run() {
  3547. this.logger.log("移除直播间小橙车弹窗模块开始运行");
  3548. _GM_addStyle(".shop-popover { display: none !important }");
  3549. }
  3550. }
  3551. __publicField(RemoveShopPopover, "runOnMultiplePages", true);
  3552. class RemoveGameParty extends BaseModule {
  3553. constructor() {
  3554. super(...arguments);
  3555. __publicField(this, "config", this.moduleStore.moduleConfig.RemoveElement.removeGameParty);
  3556. }
  3557. async run() {
  3558. this.logger.log("移除直播间幻星派对标志模块开始运行");
  3559. _GM_addStyle("#game-id { display: none !important }");
  3560. }
  3561. }
  3562. __publicField(RemoveGameParty, "runMultiple", true);
  3563. class removeGiftPopover extends BaseModule {
  3564. constructor() {
  3565. super(...arguments);
  3566. __publicField(this, "config", this.moduleStore.moduleConfig.RemoveElement.removeGiftPopover);
  3567. }
  3568. async run() {
  3569. this.logger.log("移除礼物赠送提示弹窗模块开始运行");
  3570. _GM_addStyle(".function-card { display: none !important }");
  3571. }
  3572. }
  3573. __publicField(removeGiftPopover, "runOnMultiplePages", true);
  3574. class removeMicPopover extends BaseModule {
  3575. constructor() {
  3576. super(...arguments);
  3577. __publicField(this, "config", this.moduleStore.moduleConfig.RemoveElement.removeMicPopover);
  3578. }
  3579. async run() {
  3580. this.logger.log("移除连麦状态提示模块开始运行");
  3581. _GM_addStyle(".lin-mic-cntr { display: none !important }");
  3582. }
  3583. }
  3584. __publicField(removeMicPopover, "runOnMultiplePages", true);
  3585. class RemoveComboCard extends BaseModule {
  3586. constructor() {
  3587. super(...arguments);
  3588. __publicField(this, "config", this.moduleStore.moduleConfig.RemoveElement.removeComboCard);
  3589. }
  3590. async run() {
  3591. this.logger.log("移除直播间相同弹幕连续提示模块开始运行");
  3592. _GM_addStyle("#combo-card { display: none !important }");
  3593. }
  3594. }
  3595. __publicField(RemoveComboCard, "runOnMultiplePages", true);
  3596. class RemoveRank extends BaseModule {
  3597. constructor() {
  3598. super(...arguments);
  3599. __publicField(this, "config", this.moduleStore.moduleConfig.RemoveElement.removeRank);
  3600. }
  3601. async run() {
  3602. this.logger.log("移除排行榜模块开始运行");
  3603. _GM_addStyle(".popular-and-hot-rank { display: none !important }");
  3604. }
  3605. }
  3606. __publicField(RemoveRank, "runOnMultiplePages", true);
  3607. class RemoveHeaderStuff extends BaseModule {
  3608. constructor() {
  3609. super(...arguments);
  3610. __publicField(this, "config", this.moduleStore.moduleConfig.RemoveElement.removeHeaderStuff);
  3611. }
  3612. async run() {
  3613. this.logger.log("移除活动入口模块开始运行");
  3614. _GM_addStyle(".header-info-ctnr .rows-ctnr .lower-row .right-ctnr { display: none !important }");
  3615. }
  3616. }
  3617. __publicField(RemoveHeaderStuff, "runOnMultiplePages", true);
  3618. class RemoveFlipView extends BaseModule {
  3619. constructor() {
  3620. super(...arguments);
  3621. __publicField(this, "config", this.moduleStore.moduleConfig.RemoveElement.removeFlipView);
  3622. }
  3623. async run() {
  3624. this.logger.log("移除礼物栏下方广告模块开始运行");
  3625. _GM_addStyle(".flip-view { display: none !important }");
  3626. }
  3627. }
  3628. __publicField(RemoveFlipView, "runOnMultiplePages", true);
  3629. class RemoveRecommendRoom extends BaseModule {
  3630. constructor() {
  3631. super(...arguments);
  3632. __publicField(this, "config", this.moduleStore.moduleConfig.RemoveElement.removeRecommendRoom);
  3633. }
  3634. async run() {
  3635. this.logger.log("移除礼物栏下方推荐直播间模块开始运行");
  3636. _GM_addStyle(".room-info-ctnr { display: none !important }");
  3637. }
  3638. }
  3639. __publicField(RemoveRecommendRoom, "runOnMultiplePages", true);
  3640. class RemoveLiveMosaic extends BaseModule {
  3641. constructor() {
  3642. super(...arguments);
  3643. __publicField(this, "config", this.moduleStore.moduleConfig.RemoveElement.removeLiveMosaic);
  3644. }
  3645. async run() {
  3646. this.logger.log("移除直播间马赛克模块开始运行");
  3647. _GM_addStyle("#web-player-module-area-mask-panel { opacity: 0 !important }");
  3648. }
  3649. }
  3650. __publicField(RemoveLiveMosaic, "runOnMultiplePages", true);
  3651. const otherModules = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  3652. __proto__: null,
  3653. DailyTask_LiveTask_LightTask: LightTask,
  3654. DailyTask_LiveTask_SignTask: SignTask,
  3655. DailyTask_LiveTask_WatchTask: WatchTask2,
  3656. DailyTask_MainSiteTask_CoinTask: CoinTask,
  3657. DailyTask_MainSiteTask_LoginTask: LoginTask,
  3658. DailyTask_MainSiteTask_ShareTask: ShareTask,
  3659. DailyTask_MainSiteTask_WatchTask: WatchTask$1,
  3660. DailyTask_OtherTask_CoinToSilverTask: CoinToSilverTask,
  3661. DailyTask_OtherTask_GetYearVipPrivilegeTask: GetYearVipPrivilegeTask,
  3662. DailyTask_OtherTask_GroupSignTask: GroupSignTask,
  3663. DailyTask_OtherTask_SilverToCoinTask: SilverToCoinTask,
  3664. EnhanceExperience_BanP2P: BanP2P,
  3665. EnhanceExperience_Invisibility: Invisibility,
  3666. EnhanceExperience_NoReport: NoReport,
  3667. EnhanceExperience_NoSleep: NoSleep,
  3668. EnhanceExperience_SwitchLiveStreamQuality: SwitchLiveStreamQuality,
  3669. RemoveElement_RemoveComboCard: RemoveComboCard,
  3670. RemoveElement_RemoveFlipView: RemoveFlipView,
  3671. RemoveElement_RemoveGameParty: RemoveGameParty,
  3672. RemoveElement_RemoveGiftPopover: removeGiftPopover,
  3673. RemoveElement_RemoveHeaderStuff: RemoveHeaderStuff,
  3674. RemoveElement_RemoveLiveMosaic: RemoveLiveMosaic,
  3675. RemoveElement_RemoveLiveWaterMark: RemoveLiveWaterMark,
  3676. RemoveElement_RemoveMicPopover: removeMicPopover,
  3677. RemoveElement_RemovePKBox: RemovePKBox,
  3678. RemoveElement_RemoveRank: RemoveRank,
  3679. RemoveElement_RemoveRecommendRoom: RemoveRecommendRoom,
  3680. RemoveElement_RemoveShopPopover: RemoveShopPopover
  3681. }, Symbol.toStringTag, { value: "Module" }));
  3682. function mitt(n) {
  3683. return { all: n = n || /* @__PURE__ */ new Map(), on: function(t, e) {
  3684. var i = n.get(t);
  3685. i ? i.push(e) : n.set(t, [e]);
  3686. }, off: function(t, e) {
  3687. var i = n.get(t);
  3688. i && (e ? i.splice(i.indexOf(e) >>> 0, 1) : n.set(t, []));
  3689. }, emit: function(t, e) {
  3690. var i = n.get(t);
  3691. i && i.slice().map(function(n2) {
  3692. n2(e);
  3693. }), (i = n.get("*")) && i.slice().map(function(n2) {
  3694. n2(t, e);
  3695. });
  3696. } };
  3697. }
  3698. function mittOnce(all) {
  3699. const emitter = mitt(all);
  3700. return {
  3701. // 继承原生 mitt 的方法
  3702. ...emitter,
  3703. once(type, handler) {
  3704. emitter.on(type, function fn(evt) {
  3705. emitter.off(type, fn);
  3706. handler(evt);
  3707. });
  3708. }
  3709. };
  3710. }
  3711. const useCacheStore = pinia$1.defineStore("cache", () => {
  3712. const cache = vue.reactive(Storage.getCache());
  3713. const currentScriptType = vue.ref("Main");
  3714. function startMainBLTHAliveHeartBeat() {
  3715. cache.lastAliveHeartBeatTime = Date.now();
  3716. const timer = setInterval(() => cache.lastAliveHeartBeatTime = Date.now(), 5e3);
  3717. window.addEventListener("unload", () => {
  3718. clearInterval(timer);
  3719. cache.lastAliveHeartBeatTime = 0;
  3720. });
  3721. }
  3722. function checkCurrentScriptType() {
  3723. if (cache.lastAliveHeartBeatTime !== 0 && Date.now() - cache.lastAliveHeartBeatTime < 8e3) {
  3724. if (sessionStorage.getItem("main_blth_flag") === null) {
  3725. currentScriptType.value = "Other";
  3726. } else {
  3727. currentScriptType.value = "SubMain";
  3728. }
  3729. } else {
  3730. currentScriptType.value = "Main";
  3731. sessionStorage.setItem("main_blth_flag", "🚩");
  3732. }
  3733. }
  3734. vue.watch(cache, (newCache) => Storage.setCache(newCache));
  3735. return {
  3736. cache,
  3737. currentScriptType,
  3738. startMainBLTHAliveHeartBeat,
  3739. checkCurrentScriptType
  3740. };
  3741. });
  3742. const defaultModuleStatus = {
  3743. DailyTasks: {
  3744. MainSiteTasks: {
  3745. login: "",
  3746. watch: "",
  3747. coin: "",
  3748. share: ""
  3749. },
  3750. LiveTasks: {
  3751. sign: "",
  3752. medalTasks: {
  3753. light: "",
  3754. watch: ""
  3755. }
  3756. },
  3757. OtherTasks: {
  3758. groupSign: "",
  3759. silverToCoin: "",
  3760. coinToSilver: "",
  3761. getYearVipPrivilege: ""
  3762. }
  3763. }
  3764. };
  3765. const allAndTopFrameModuleNames = [];
  3766. function loadDefaultModules() {
  3767. const cacheStore2 = useCacheStore();
  3768. const promiseArray = [];
  3769. for (const [name, module] of Object.entries(defaultModules)) {
  3770. if (module.runOnMultiplePages || cacheStore2.currentScriptType !== "Other") {
  3771. promiseArray.push(runModule(module, name));
  3772. }
  3773. }
  3774. return Promise.allSettled(promiseArray);
  3775. }
  3776. function runModule(module, name) {
  3777. const moduleInstance = new module(name);
  3778. if (moduleInstance.isEnabled()) {
  3779. return moduleInstance.run();
  3780. }
  3781. }
  3782. const useModuleStore = pinia$1.defineStore("module", () => {
  3783. const moduleConfig = vue.reactive(Storage.getModuleConfig());
  3784. const emitter = mittOnce();
  3785. const moduleStatus = vue.reactive(defaultModuleStatus);
  3786. function loadModules(isOnTargetFrame) {
  3787. const cacheStore2 = useCacheStore();
  3788. if (isOnTargetFrame === "unknown") {
  3789. for (const [name, module] of Object.entries(otherModules)) {
  3790. if (module.onFrame === "all" || module.onFrame === "top" && isSelfTopFrame()) {
  3791. if (module.runOnMultiplePages || cacheStore2.currentScriptType !== "Other") {
  3792. if (!module.runAfterDefault) {
  3793. waitForMoment(module.runAt).then(() => runModule(module, name));
  3794. allAndTopFrameModuleNames.push(name);
  3795. }
  3796. }
  3797. }
  3798. }
  3799. } else {
  3800. const moduleAfterDefault = {};
  3801. const defaultModulesLoadingResult = loadDefaultModules();
  3802. for (const [name, module] of Object.entries(otherModules)) {
  3803. if (module.onFrame === "target" || module.onFrame === "top" && isSelfTopFrame() && !allAndTopFrameModuleNames.includes(name) || module.onFrame === "all" && !allAndTopFrameModuleNames.includes(name)) {
  3804. if (module.runOnMultiplePages || cacheStore2.currentScriptType !== "Other") {
  3805. if (module.runAfterDefault) {
  3806. moduleAfterDefault[name] = module;
  3807. } else {
  3808. waitForMoment(module.runAt).then(() => runModule(module, name));
  3809. }
  3810. }
  3811. }
  3812. }
  3813. defaultModulesLoadingResult.then((results) => {
  3814. for (const result of results) {
  3815. if (result.status === "rejected") {
  3816. const error = result.reason;
  3817. if (error instanceof ModuleCriticalError) {
  3818. new Logger(error.moduleName).error(error.message);
  3819. return;
  3820. } else if (error instanceof ModuleError) {
  3821. new Logger(error.moduleName).error(error.message);
  3822. } else {
  3823. new Logger("ModuleStore").error(`意外错误: ${error.message}`);
  3824. return;
  3825. }
  3826. }
  3827. }
  3828. for (const [name, module] of Object.entries(moduleAfterDefault)) {
  3829. waitForMoment(module.runAt).then(() => runModule(module, name));
  3830. }
  3831. });
  3832. }
  3833. }
  3834. vue.watch(
  3835. moduleConfig,
  3836. _.debounce((newModuleConfig) => Storage.setModuleConfig(newModuleConfig), 250, {
  3837. leading: true,
  3838. trailing: true
  3839. })
  3840. );
  3841. (function clearStatus() {
  3842. setTimeout(() => {
  3843. deepestIterate(moduleStatus, (_value, path) => {
  3844. _.set(moduleStatus, path, "");
  3845. });
  3846. clearStatus();
  3847. }, delayToNextMoment(0, 0).ms);
  3848. })();
  3849. return {
  3850. moduleConfig,
  3851. emitter,
  3852. moduleStatus,
  3853. loadModules
  3854. };
  3855. });
  3856. const helpInfo = {
  3857. DailyTasks: {
  3858. MainSiteTasks: {
  3859. login: {
  3860. title: "每日登录(不可用)",
  3861. message: "完成主站的每日登录(不可用)任务。"
  3862. },
  3863. watch: {
  3864. title: "每日观看视频",
  3865. message: vue.h("p", [
  3866. vue.h("div", "完成主站的每日观看视频任务。"),
  3867. vue.h("div", "从动态中选取视频观看,会产生观看历史记录。")
  3868. ])
  3869. },
  3870. coin: {
  3871. title: "每日投币",
  3872. message: vue.h("p", [
  3873. vue.h("div", "完成主站的每日投币任务。"),
  3874. vue.h("div", "从动态中选取视频投币,会根据你今天已经投过的币的数量计算还要投几个币。")
  3875. ])
  3876. },
  3877. share: {
  3878. title: "每日分享视频",
  3879. message: vue.h("p", [
  3880. vue.h("div", "完成主站的每日分享视频任务。"),
  3881. vue.h("div", "不会真的分享到某处。")
  3882. ])
  3883. }
  3884. },
  3885. LiveTasks: {
  3886. sign: {
  3887. title: "直播签到",
  3888. message: vue.h("p", [vue.h("div", "完成直播签到任务。")])
  3889. },
  3890. medalTasks: {
  3891. list: {
  3892. title: "黑白名单 / 排序模式",
  3893. message: vue.h("p", [
  3894. vue.h(
  3895. "div",
  3896. "为了更精细地控制为哪些粉丝勋章执行点亮熄灭勋章和观看直播任务,你可以使用黑名单或白名单模式。"
  3897. ),
  3898. vue.h("div", [
  3899. vue.h("li", [
  3900. vue.h("span", "黑名单:仅为"),
  3901. vue.h("strong", "不在"),
  3902. vue.h("span", "名单中的粉丝勋章执行任务。")
  3903. ]),
  3904. vue.h("li", [
  3905. vue.h("span", "白名单:仅为"),
  3906. vue.h("strong", "在"),
  3907. vue.h("span", "名单中的粉丝勋章执行任务。")
  3908. ])
  3909. ]),
  3910. vue.h("div", "点击编辑名单按钮,然后使用第一列的多选框即可编辑名单中的粉丝勋章。"),
  3911. vue.h(
  3912. "div",
  3913. "使用白名单模式时,可点击【编辑名单】窗口右下角的按钮即可从【常规模式】切换到【排序模式】。"
  3914. ),
  3915. vue.h("div", "在排序模式下,你可以调整脚本执行观看任务的粉丝勋章顺序。"),
  3916. vue.h("div", [
  3917. vue.h("li", "使用鼠标拖拽表格中的行来调整顺序。"),
  3918. vue.h("li", "拖拽行至表格的顶部和底部可以触发滚动。")
  3919. ])
  3920. ])
  3921. },
  3922. light: {
  3923. main: {
  3924. title: "点亮熄灭勋章",
  3925. message: vue.h("p", [
  3926. vue.h("div", "在你的每个已熄灭的粉丝勋章对应的直播间完成点亮任务,从而点亮粉丝勋章。"),
  3927. vue.h("div", "支持两种点亮方式,可自由选择:"),
  3928. vue.h("div", [
  3929. vue.h("li", [vue.h("span", "点赞(不推荐):点赞30次")]),
  3930. vue.h("li", [vue.h("strong", "发送弹幕(推荐):"), vue.h("span", "发送弹幕1条")])
  3931. ])
  3932. ])
  3933. },
  3934. like: {
  3935. title: "点赞",
  3936. message: vue.h("p", [
  3937. vue.h("div", "在已熄灭粉丝勋章对应的直播间给主播点赞,点亮粉丝勋章。"),
  3938. vue.h("div", [
  3939. vue.h("li", [vue.h("span", "点赞次数为略微超过任务要求的随机值。")]),
  3940. vue.h("li", [vue.h("span", "部分直播间无法完成该任务,原因未知。")])
  3941. ]),
  3942. vue.h("div", [
  3943. vue.h("strong", "注意:"),
  3944. vue.h("span", "点赞只能点亮正在直播的直播间对应的粉丝勋章。")
  3945. ])
  3946. ])
  3947. },
  3948. danmu: {
  3949. title: "发送弹幕",
  3950. message: vue.h("p", [
  3951. vue.h("div", "在已熄灭粉丝勋章对应的直播间发送一条弹幕,点亮粉丝勋章。"),
  3952. vue.h("div", [
  3953. vue.h("span", "点击编辑弹幕按钮编辑发送的弹幕,脚本会从中按顺序循环抽取弹幕发送。"),
  3954. vue.h("span", "部分直播间无法完成该任务,可能的原因有:"),
  3955. vue.h("div", [
  3956. vue.h("li", "你被禁言了"),
  3957. vue.h("li", "发言有粉丝勋章等级要求"),
  3958. vue.h("li", [
  3959. vue.h("span", "特殊直播间(比如"),
  3960. vue.h(
  3961. "a",
  3962. { href: "https://live.bilibili.com/54", rel: "noreferrer", target: "_blank" },
  3963. "54"
  3964. ),
  3965. vue.h("span", ")")
  3966. ])
  3967. ])
  3968. ])
  3969. ])
  3970. }
  3971. },
  3972. watch: {
  3973. title: "观看直播",
  3974. message: vue.h("p", [
  3975. vue.h("div", "完成粉丝勋章的观看直播任务。"),
  3976. vue.h("div", [
  3977. vue.h("li", "部分直播间因为没有设置直播分区导致任务无法完成。"),
  3978. vue.h("li", "主播当前是否开播不会影响该任务的完成。"),
  3979. vue.h(
  3980. "li",
  3981. "根据目前的亲密度规则,将每个直播间的观看时长设置为25分钟即可获得全部亲密度。"
  3982. )
  3983. ]),
  3984. vue.h("div", [
  3985. vue.h("strong", "注意:"),
  3986. vue.h(
  3987. "span",
  3988. "使用本功能时不能以任何方式观看直播(网页、APP、电视),否则可能无法获得任何亲密度。"
  3989. )
  3990. ])
  3991. ])
  3992. }
  3993. }
  3994. },
  3995. OtherTasks: {
  3996. groupSign: {
  3997. title: "应援团签到",
  3998. message: "完成应援团签到任务。"
  3999. },
  4000. silverToCoin: {
  4001. title: "银瓜子换硬币",
  4002. message: vue.h("p", [
  4003. vue.h("div", "把银瓜子兑换为硬币。"),
  4004. vue.h("div", "具体兑换规则请点击直播间页面的“立即充值→银瓜子商店”查看。")
  4005. ])
  4006. },
  4007. coinToSilver: {
  4008. title: "硬币换银瓜子",
  4009. message: vue.h("p", [
  4010. vue.h("div", "把硬币兑换为银瓜子。"),
  4011. vue.h("div", "具体兑换规则请点击直播间页面的“立即充值→银瓜子商店”查看。")
  4012. ])
  4013. },
  4014. getYearVipPrivilege: {
  4015. title: "领取年度大会员权益",
  4016. message: vue.h("p", [
  4017. vue.h("div", "自动领取年度大会员权益。"),
  4018. vue.h("div", [
  4019. vue.h("span", "具体权益请前往"),
  4020. vue.h(
  4021. "a",
  4022. {
  4023. href: "https://account.bilibili.com/account/big/myPackage",
  4024. rel: "noreferrer",
  4025. target: "_blank"
  4026. },
  4027. "卡券包"
  4028. ),
  4029. vue.h("span", "查看。")
  4030. ])
  4031. ])
  4032. }
  4033. }
  4034. },
  4035. EnhanceExperience: {
  4036. switchLiveStreamQuality: {
  4037. title: "自动切换画质",
  4038. message: vue.h("p", [
  4039. vue.h("div", "打开直播间后自动把播放器切换到指定画质。"),
  4040. vue.h("div", "如果指定画质不存在,则还是使用B站的默认画质。")
  4041. ])
  4042. },
  4043. banp2p: {
  4044. title: "禁用P2P",
  4045. message: vue.h("p", [
  4046. vue.h("div", "禁用直播流的P2P上传/下载"),
  4047. vue.h(
  4048. "div",
  4049. "B站使用WebRTC技术把许多浏览器点对点(P2P)地连接起来,实现视频流和音频流的传输。这样做是为了减轻B站服务器的压力,但是会占用你一定的上行带宽(大约几百kb每秒)。如果你不想被占用上行带宽,可以开启该功能。若开启后发现观看直播时有明显卡顿,请关闭。"
  4050. )
  4051. ])
  4052. },
  4053. noReport: {
  4054. title: "拦截日志数据上报",
  4055. message: vue.h("p", [
  4056. vue.h("div", "禁止B站上报日志数据。"),
  4057. vue.h("div", [
  4058. vue.h(
  4059. "span",
  4060. "B站会实时地上报大量日志信息,比如直播观看情况、代码报错等等。开启本功能后绝大多数日志上报都会被劫持或拦截并返回一个成功的响应。相比于带有广告拦截功能的浏览器拓展,比如"
  4061. ),
  4062. vue.h(
  4063. "a",
  4064. {
  4065. href: "https://github.com/gorhill/uBlock",
  4066. rel: "noreferrer",
  4067. target: "_blank"
  4068. },
  4069. "uBlock Origin"
  4070. ),
  4071. vue.h(
  4072. "span",
  4073. ",本功能会通过劫持的方式从根源上阻止部分日志上报,并模拟成功的响应来尽可能地减少B站代码的报错。理论上来说这样做会有更好的性能表现。"
  4074. )
  4075. ])
  4076. ])
  4077. },
  4078. noSleep: {
  4079. title: "屏蔽挂机检测",
  4080. message: vue.h("p", [
  4081. vue.h("div", "屏蔽B站直播间的挂机检测。"),
  4082. vue.h(
  4083. "div",
  4084. "如果长时间没有操作,会提示“检测到您已离开当前屏幕,倒计时后即将暂停播放”。开启本功能后即可避免这种情况。"
  4085. )
  4086. ])
  4087. },
  4088. invisibility: {
  4089. title: "隐身入场",
  4090. message: vue.h("p", [vue.h("div", "进入直播间时其他人不会收到提示,但还是会出现在高能用户榜单上。")])
  4091. }
  4092. },
  4093. RemoveElement: {
  4094. removePKBox: {
  4095. title: "移除大乱斗元素",
  4096. message: "移除直播间的大乱斗元素(进度条,弹出的提示等)。"
  4097. },
  4098. removeLiveWaterMark: {
  4099. title: "移除直播间水印",
  4100. message: "移除直播画面左上角的水印。"
  4101. },
  4102. removeShopPopover: {
  4103. title: "移除直播间小橙车弹窗",
  4104. message: "移除直播间左上角的小橙车弹窗。"
  4105. },
  4106. removeGameParty: {
  4107. title: "移除直播间幻星派对标志",
  4108. message: "移除直播间右下角的幻星派对标志。"
  4109. },
  4110. removeGiftPopover: {
  4111. title: "移除礼物赠送提示弹窗",
  4112. message: "移除直播间右下角的礼物赠送提示弹窗(赠送一个牛蛙牛蛙支持主播)。"
  4113. },
  4114. removeMicPopover: {
  4115. title: "移除连麦状态提示",
  4116. message: "移除直播间左上角的连麦提示弹窗(连线功能只能在手机端使用,快使用手机登录(不可用)吧~)。"
  4117. },
  4118. removeComboCard: {
  4119. title: "移除直播间相同弹幕连续提示",
  4120. message: "移除直播间相同弹幕连续提示。"
  4121. },
  4122. removeRank: {
  4123. title: "移除排行榜",
  4124. message: "移除直播画面上方的人气榜/航海榜,赠送人气票的入口也在这里。"
  4125. },
  4126. removeHeaderStuff: {
  4127. title: "移除直播画面上方杂项",
  4128. message: "移除直播画面上方各种杂七杂八的东西,比如排行榜、活动轮播图等。"
  4129. },
  4130. removeFlipView: {
  4131. title: "移除礼物栏下方广告",
  4132. message: "移除礼物栏下方广告。"
  4133. },
  4134. removeRecommendRoom: {
  4135. title: "移除礼物栏下方推荐直播间",
  4136. message: "移除礼物栏下方推荐直播间。"
  4137. },
  4138. removeLiveMosaic: {
  4139. title: "移除直播间马赛克",
  4140. message: "移除部分直播间特有的马赛克。"
  4141. }
  4142. }
  4143. };
  4144. const _sfc_main$a = /* @__PURE__ */ vue.defineComponent({
  4145. __name: "MainSiteTasks",
  4146. setup(__props) {
  4147. const moduleStore2 = useModuleStore();
  4148. const config = moduleStore2.moduleConfig.DailyTasks.MainSiteTasks;
  4149. const status = moduleStore2.moduleStatus.DailyTasks.MainSiteTasks;
  4150. return (_ctx, _cache) => {
  4151. const _component_el_switch = vue.resolveComponent("el-switch");
  4152. const _component_Info = vue.resolveComponent("Info");
  4153. const _component_TaskStatus = vue.resolveComponent("TaskStatus");
  4154. const _component_el_space = vue.resolveComponent("el-space");
  4155. const _component_el_row = vue.resolveComponent("el-row");
  4156. const _component_el_option = vue.resolveComponent("el-option");
  4157. const _component_el_select = vue.resolveComponent("el-select");
  4158. const _component_el_text = vue.resolveComponent("el-text");
  4159. const _component_el_divider = vue.resolveComponent("el-divider");
  4160. const _component_el_link = vue.resolveComponent("el-link");
  4161. return vue.openBlock(), vue.createElementBlock("div", null, [
  4162. vue.createVNode(_component_el_row, null, {
  4163. default: vue.withCtx(() => [
  4164. vue.createVNode(_component_el_space, {
  4165. wrap: "",
  4166. size: [8, 0]
  4167. }, {
  4168. default: vue.withCtx(() => [
  4169. vue.createVNode(_component_el_switch, {
  4170. modelValue: vue.unref(config).login.enabled,
  4171. "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => vue.unref(config).login.enabled = $event),
  4172. "active-text": "每日登录(不可用)"
  4173. }, null, 8, ["modelValue"]),
  4174. vue.createVNode(_component_Info, {
  4175. item: vue.unref(helpInfo).DailyTasks.MainSiteTasks.login
  4176. }, null, 8, ["item"]),
  4177. vue.createVNode(_component_TaskStatus, {
  4178. status: vue.unref(status).login
  4179. }, null, 8, ["status"])
  4180. ]),
  4181. _: 1
  4182. })
  4183. ]),
  4184. _: 1
  4185. }),
  4186. vue.createVNode(_component_el_row, null, {
  4187. default: vue.withCtx(() => [
  4188. vue.createVNode(_component_el_space, {
  4189. wrap: "",
  4190. size: [8, 0]
  4191. }, {
  4192. default: vue.withCtx(() => [
  4193. vue.createVNode(_component_el_switch, {
  4194. modelValue: vue.unref(config).watch.enabled,
  4195. "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => vue.unref(config).watch.enabled = $event),
  4196. "active-text": "每日观看视频"
  4197. }, null, 8, ["modelValue"]),
  4198. vue.createVNode(_component_Info, {
  4199. item: vue.unref(helpInfo).DailyTasks.MainSiteTasks.watch
  4200. }, null, 8, ["item"]),
  4201. vue.createVNode(_component_TaskStatus, {
  4202. status: vue.unref(status).watch
  4203. }, null, 8, ["status"])
  4204. ]),
  4205. _: 1
  4206. })
  4207. ]),
  4208. _: 1
  4209. }),
  4210. vue.createVNode(_component_el_row, null, {
  4211. default: vue.withCtx(() => [
  4212. vue.createVNode(_component_el_space, {
  4213. wrap: "",
  4214. size: [8, 0]
  4215. }, {
  4216. default: vue.withCtx(() => [
  4217. vue.createVNode(_component_el_switch, {
  4218. modelValue: vue.unref(config).coin.enabled,
  4219. "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => vue.unref(config).coin.enabled = $event),
  4220. "active-text": "每日投币"
  4221. }, null, 8, ["modelValue"]),
  4222. vue.createVNode(_component_el_select, {
  4223. modelValue: vue.unref(config).coin.num,
  4224. "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => vue.unref(config).coin.num = $event),
  4225. placeholder: "Select",
  4226. style: { "width": "64px" }
  4227. }, {
  4228. default: vue.withCtx(() => [
  4229. (vue.openBlock(), vue.createElementBlock(vue.Fragment, null, vue.renderList(5, (i) => {
  4230. return vue.createVNode(_component_el_option, {
  4231. key: i,
  4232. label: i,
  4233. value: i
  4234. }, null, 8, ["label", "value"]);
  4235. }), 64))
  4236. ]),
  4237. _: 1
  4238. }, 8, ["modelValue"]),
  4239. vue.createVNode(_component_el_text, null, {
  4240. default: vue.withCtx(() => _cache[5] || (_cache[5] = [
  4241. vue.createTextVNode("个")
  4242. ])),
  4243. _: 1
  4244. }),
  4245. vue.createVNode(_component_Info, {
  4246. item: vue.unref(helpInfo).DailyTasks.MainSiteTasks.coin
  4247. }, null, 8, ["item"]),
  4248. vue.createVNode(_component_TaskStatus, {
  4249. status: vue.unref(status).coin
  4250. }, null, 8, ["status"])
  4251. ]),
  4252. _: 1
  4253. })
  4254. ]),
  4255. _: 1
  4256. }),
  4257. vue.createVNode(_component_el_row, null, {
  4258. default: vue.withCtx(() => [
  4259. vue.createVNode(_component_el_space, {
  4260. wrap: "",
  4261. size: [8, 0]
  4262. }, {
  4263. default: vue.withCtx(() => [
  4264. vue.createVNode(_component_el_switch, {
  4265. modelValue: vue.unref(config).share.enabled,
  4266. "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => vue.unref(config).share.enabled = $event),
  4267. "active-text": "每日分享视频"
  4268. }, null, 8, ["modelValue"]),
  4269. vue.createVNode(_component_Info, {
  4270. item: vue.unref(helpInfo).DailyTasks.MainSiteTasks.share
  4271. }, null, 8, ["item"]),
  4272. vue.createVNode(_component_TaskStatus, {
  4273. status: vue.unref(status).share
  4274. }, null, 8, ["status"])
  4275. ]),
  4276. _: 1
  4277. })
  4278. ]),
  4279. _: 1
  4280. }),
  4281. vue.createVNode(_component_el_divider),
  4282. vue.createVNode(_component_el_row, null, {
  4283. default: vue.withCtx(() => [
  4284. vue.createVNode(_component_el_text, null, {
  4285. default: vue.withCtx(() => [
  4286. vue.createVNode(_component_el_text, null, {
  4287. default: vue.withCtx(() => _cache[6] || (_cache[6] = [
  4288. vue.createTextVNode("  主站每日任务的完成情况可在")
  4289. ])),
  4290. _: 1
  4291. }),
  4292. vue.createVNode(_component_el_link, {
  4293. rel: "noreferrer",
  4294. type: "primary",
  4295. href: "https://account.bilibili.com/account/home",
  4296. target: "_blank",
  4297. style: { "vertical-align": "unset" }
  4298. }, {
  4299. default: vue.withCtx(() => _cache[7] || (_cache[7] = [
  4300. vue.createTextVNode("个人中心")
  4301. ])),
  4302. _: 1
  4303. }),
  4304. vue.createVNode(_component_el_text, null, {
  4305. default: vue.withCtx(() => _cache[8] || (_cache[8] = [
  4306. vue.createTextVNode("查看。")
  4307. ])),
  4308. _: 1
  4309. }),
  4310. vue.createVNode(_component_el_text, null, {
  4311. default: vue.withCtx(() => _cache[9] || (_cache[9] = [
  4312. vue.createTextVNode("数据更新可能有一定的延时。")
  4313. ])),
  4314. _: 1
  4315. })
  4316. ]),
  4317. _: 1
  4318. })
  4319. ]),
  4320. _: 1
  4321. })
  4322. ]);
  4323. };
  4324. }
  4325. });
  4326. const _hoisted_1$1 = { class: "avatar-wrap" };
  4327. const _sfc_main$9 = /* @__PURE__ */ vue.defineComponent({
  4328. __name: "LiveTasks",
  4329. setup(__props) {
  4330. const moduleStore2 = useModuleStore();
  4331. const biliStore = useBiliStore();
  4332. const uiStore = useUIStore();
  4333. const medalTableMaxHeight = screen.height * 0.55;
  4334. const danmuTableMaxHeight = screen.height * 0.5;
  4335. const config = moduleStore2.moduleConfig.DailyTasks.LiveTasks;
  4336. const status = moduleStore2.moduleStatus.DailyTasks.LiveTasks;
  4337. const medalDanmuPanelVisible = vue.ref(false);
  4338. const danmuTableData = vue.computed(
  4339. () => config.medalTasks.light.danmuList.map((danmu) => {
  4340. return { content: danmu };
  4341. })
  4342. );
  4343. const handleEditDanmu = (index, row) => {
  4344. ElementPlus.ElMessageBox.prompt("请输入新的弹幕内容", "修改弹幕", {
  4345. confirmButtonText: "确认",
  4346. cancelButtonText: "取消",
  4347. inputPattern: /^.{1,30}$/,
  4348. inputErrorMessage: "弹幕内容不得为空且长度不能超过30",
  4349. inputValue: row.content,
  4350. lockScroll: false
  4351. }).then(({ value }) => {
  4352. config.medalTasks.light.danmuList[index] = value;
  4353. }).catch(() => {
  4354. });
  4355. };
  4356. const handleDeleteDanmu = (index) => {
  4357. if (config.medalTasks.light.danmuList.length === 1) {
  4358. ElementPlus.ElMessage.warning({
  4359. message: "至少要有一条弹幕",
  4360. appendTo: ".el-dialog"
  4361. });
  4362. return;
  4363. }
  4364. config.medalTasks.light.danmuList.splice(index, 1);
  4365. };
  4366. const handleAddDanmu = () => {
  4367. ElementPlus.ElMessageBox.prompt("请输入新增的弹幕内容", "新增弹幕", {
  4368. confirmButtonText: "确认",
  4369. cancelButtonText: "取消",
  4370. inputPattern: /^.{1,30}$/,
  4371. inputErrorMessage: "弹幕内容不得为空且长度不能超过30",
  4372. lockScroll: false
  4373. }).then(({ value }) => {
  4374. config.medalTasks.light.danmuList.push(value);
  4375. }).catch(() => {
  4376. });
  4377. };
  4378. const medalInfoPanelVisible = vue.ref(false);
  4379. const medalInfoTableData = vue.computed({
  4380. get() {
  4381. const medals = biliStore.filteredFansMedals.map((medal) => ({
  4382. avatar: medal.anchor_info.avatar,
  4383. nick_name: medal.anchor_info.nick_name,
  4384. medal_name: medal.medal.medal_name,
  4385. medal_level: medal.medal.level,
  4386. roomid: medal.room_info.room_id
  4387. }));
  4388. if (uiStore.uiConfig.medalInfoPanelSortMode) {
  4389. const filteredMedals = medals.filter(
  4390. (medal) => config.medalTasks.isWhiteList ? config.medalTasks.roomidList.includes(medal.roomid) : !config.medalTasks.roomidList.includes(medal.roomid)
  4391. );
  4392. const orderMap = arrayToMap(config.medalTasks.roomidList);
  4393. return filteredMedals.sort((a, b) => orderMap.get(a.roomid) - orderMap.get(b.roomid));
  4394. }
  4395. return medals;
  4396. },
  4397. set(newValue) {
  4398. config.medalTasks.roomidList = newValue.map((row) => row.roomid);
  4399. }
  4400. });
  4401. const medalInfoLoading = vue.ref(false);
  4402. let firstClickEditList = true;
  4403. const handleEditList = async () => {
  4404. medalInfoPanelVisible.value = true;
  4405. if (firstClickEditList) {
  4406. firstClickEditList = false;
  4407. await vue.nextTick();
  4408. if (!biliStore.fansMedals) {
  4409. medalInfoLoading.value = true;
  4410. vue.watch(
  4411. medalInfoTableData,
  4412. (newData) => {
  4413. vue.nextTick(() => {
  4414. initSelection(newData);
  4415. medalInfoLoading.value = false;
  4416. });
  4417. },
  4418. { once: true }
  4419. );
  4420. moduleStore2.emitter.emit("Default_FansMedals", {
  4421. module: "LiveTasks"
  4422. });
  4423. } else {
  4424. initSelection(medalInfoTableData.value);
  4425. }
  4426. }
  4427. };
  4428. const medalInfoTableRef = vue.ref();
  4429. const initSelection = (rows) => {
  4430. if (rows) {
  4431. config.medalTasks.roomidList.forEach((roomid, index) => {
  4432. var _a;
  4433. const row = rows.find((row2) => row2.roomid === roomid);
  4434. if (row) {
  4435. (_a = medalInfoTableRef.value) == null ? void 0 : _a.toggleRowSelection(row, true);
  4436. } else {
  4437. config.medalTasks.roomidList.splice(index, 1);
  4438. }
  4439. });
  4440. }
  4441. };
  4442. function handleSelect(selection) {
  4443. config.medalTasks.roomidList = selection.map((row) => row.roomid);
  4444. }
  4445. function handleRowClick(row) {
  4446. var _a, _b;
  4447. (_a = medalInfoTableRef.value) == null ? void 0 : _a.toggleRowSelection(row);
  4448. const selection = (_b = medalInfoTableRef.value) == null ? void 0 : _b.getSelectionRows();
  4449. config.medalTasks.roomidList = selection.map((row2) => row2.roomid);
  4450. }
  4451. return (_ctx, _cache) => {
  4452. const _component_el_switch = vue.resolveComponent("el-switch");
  4453. const _component_Info = vue.resolveComponent("Info");
  4454. const _component_TaskStatus = vue.resolveComponent("TaskStatus");
  4455. const _component_el_space = vue.resolveComponent("el-space");
  4456. const _component_el_row = vue.resolveComponent("el-row");
  4457. const _component_el_divider = vue.resolveComponent("el-divider");
  4458. const _component_SemiSelect = vue.resolveComponent("SemiSelect");
  4459. const _component_el_icon = vue.resolveComponent("el-icon");
  4460. const _component_el_radio = vue.resolveComponent("el-radio");
  4461. const _component_el_button = vue.resolveComponent("el-button");
  4462. const _component_el_radio_group = vue.resolveComponent("el-radio-group");
  4463. const _component_el_option = vue.resolveComponent("el-option");
  4464. const _component_el_select = vue.resolveComponent("el-select");
  4465. const _component_el_text = vue.resolveComponent("el-text");
  4466. const _component_el_link = vue.resolveComponent("el-link");
  4467. const _component_el_table_column = vue.resolveComponent("el-table-column");
  4468. const _component_el_dialog = vue.resolveComponent("el-dialog");
  4469. const _component_el_image = vue.resolveComponent("el-image");
  4470. const _directive_loading = vue.resolveDirective("loading");
  4471. return vue.openBlock(), vue.createElementBlock("div", null, [
  4472. vue.createVNode(_component_el_row, null, {
  4473. default: vue.withCtx(() => [
  4474. vue.createVNode(_component_el_space, {
  4475. wrap: "",
  4476. size: [8, 0]
  4477. }, {
  4478. default: vue.withCtx(() => [
  4479. vue.createVNode(_component_el_switch, {
  4480. modelValue: vue.unref(config).sign.enabled,
  4481. "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => vue.unref(config).sign.enabled = $event),
  4482. "active-text": "直播签到"
  4483. }, null, 8, ["modelValue"]),
  4484. vue.createVNode(_component_Info, {
  4485. item: vue.unref(helpInfo).DailyTasks.LiveTasks.sign
  4486. }, null, 8, ["item"]),
  4487. vue.createVNode(_component_TaskStatus, {
  4488. status: vue.unref(status).sign
  4489. }, null, 8, ["status"])
  4490. ]),
  4491. _: 1
  4492. })
  4493. ]),
  4494. _: 1
  4495. }),
  4496. vue.createVNode(_component_el_divider),
  4497. vue.createVNode(_component_el_row, null, {
  4498. default: vue.withCtx(() => [
  4499. vue.createVNode(_component_el_space, {
  4500. wrap: "",
  4501. size: [8, 0]
  4502. }, {
  4503. default: vue.withCtx(() => [
  4504. vue.createVNode(_component_el_switch, {
  4505. modelValue: vue.unref(config).medalTasks.light.enabled,
  4506. "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => vue.unref(config).medalTasks.light.enabled = $event),
  4507. "active-text": "点亮熄灭勋章"
  4508. }, null, 8, ["modelValue"]),
  4509. vue.createVNode(_component_Info, {
  4510. item: vue.unref(helpInfo).DailyTasks.LiveTasks.medalTasks.light.main
  4511. }, null, 8, ["item"]),
  4512. vue.createVNode(_component_TaskStatus, {
  4513. status: vue.unref(status).medalTasks.light
  4514. }, null, 8, ["status"])
  4515. ]),
  4516. _: 1
  4517. })
  4518. ]),
  4519. _: 1
  4520. }),
  4521. vue.createVNode(_component_el_row, null, {
  4522. default: vue.withCtx(() => [
  4523. vue.createVNode(_component_el_radio_group, {
  4524. modelValue: vue.unref(config).medalTasks.light.mode,
  4525. "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => vue.unref(config).medalTasks.light.mode = $event),
  4526. class: "radio-group"
  4527. }, {
  4528. default: vue.withCtx(() => [
  4529. vue.createVNode(_component_el_row, null, {
  4530. default: vue.withCtx(() => [
  4531. vue.createVNode(_component_el_space, {
  4532. wrap: "",
  4533. size: [8, 0]
  4534. }, {
  4535. default: vue.withCtx(() => [
  4536. vue.createVNode(_component_el_icon, null, {
  4537. default: vue.withCtx(() => [
  4538. vue.createVNode(_component_SemiSelect)
  4539. ]),
  4540. _: 1
  4541. }),
  4542. vue.createVNode(_component_el_radio, { value: "like" }, {
  4543. default: vue.withCtx(() => _cache[14] || (_cache[14] = [
  4544. vue.createTextVNode("点赞")
  4545. ])),
  4546. _: 1
  4547. }),
  4548. vue.createVNode(_component_Info, {
  4549. item: vue.unref(helpInfo).DailyTasks.LiveTasks.medalTasks.light.like
  4550. }, null, 8, ["item"])
  4551. ]),
  4552. _: 1
  4553. })
  4554. ]),
  4555. _: 1
  4556. }),
  4557. vue.createVNode(_component_el_row, null, {
  4558. default: vue.withCtx(() => [
  4559. vue.createVNode(_component_el_space, {
  4560. wrap: "",
  4561. size: [8, 0]
  4562. }, {
  4563. default: vue.withCtx(() => [
  4564. vue.createVNode(_component_el_icon, null, {
  4565. default: vue.withCtx(() => [
  4566. vue.createVNode(_component_SemiSelect)
  4567. ]),
  4568. _: 1
  4569. }),
  4570. vue.createVNode(_component_el_radio, { value: "danmu" }, {
  4571. default: vue.withCtx(() => _cache[15] || (_cache[15] = [
  4572. vue.createTextVNode("发送弹幕")
  4573. ])),
  4574. _: 1
  4575. }),
  4576. vue.createVNode(_component_el_button, {
  4577. type: "primary",
  4578. size: "small",
  4579. icon: vue.unref(ElementPlusIconsVue.Edit),
  4580. onClick: _cache[2] || (_cache[2] = ($event) => medalDanmuPanelVisible.value = !medalDanmuPanelVisible.value)
  4581. }, {
  4582. default: vue.withCtx(() => _cache[16] || (_cache[16] = [
  4583. vue.createTextVNode("编辑弹幕 ")
  4584. ])),
  4585. _: 1
  4586. }, 8, ["icon"]),
  4587. vue.createVNode(_component_Info, {
  4588. item: vue.unref(helpInfo).DailyTasks.LiveTasks.medalTasks.light.danmu
  4589. }, null, 8, ["item"])
  4590. ]),
  4591. _: 1
  4592. })
  4593. ]),
  4594. _: 1
  4595. })
  4596. ]),
  4597. _: 1
  4598. }, 8, ["modelValue"])
  4599. ]),
  4600. _: 1
  4601. }),
  4602. vue.createVNode(_component_el_row, null, {
  4603. default: vue.withCtx(() => [
  4604. vue.createVNode(_component_el_space, {
  4605. wrap: "",
  4606. size: [8, 0]
  4607. }, {
  4608. default: vue.withCtx(() => [
  4609. vue.createVNode(_component_el_switch, {
  4610. modelValue: vue.unref(config).medalTasks.watch.enabled,
  4611. "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => vue.unref(config).medalTasks.watch.enabled = $event),
  4612. "active-text": "观看直播"
  4613. }, null, 8, ["modelValue"]),
  4614. vue.createVNode(_component_el_select, {
  4615. modelValue: vue.unref(config).medalTasks.watch.time,
  4616. "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => vue.unref(config).medalTasks.watch.time = $event),
  4617. placeholder: "Select",
  4618. style: { "width": "70px" }
  4619. }, {
  4620. default: vue.withCtx(() => [
  4621. (vue.openBlock(), vue.createElementBlock(vue.Fragment, null, vue.renderList(6, (i) => {
  4622. return vue.createVNode(_component_el_option, {
  4623. key: i,
  4624. label: i * 5,
  4625. value: i * 5
  4626. }, null, 8, ["label", "value"]);
  4627. }), 64))
  4628. ]),
  4629. _: 1
  4630. }, 8, ["modelValue"]),
  4631. vue.createVNode(_component_el_text, null, {
  4632. default: vue.withCtx(() => _cache[17] || (_cache[17] = [
  4633. vue.createTextVNode("分钟 / 直播间")
  4634. ])),
  4635. _: 1
  4636. }),
  4637. vue.createVNode(_component_Info, {
  4638. item: vue.unref(helpInfo).DailyTasks.LiveTasks.medalTasks.watch
  4639. }, null, 8, ["item"]),
  4640. vue.createVNode(_component_TaskStatus, {
  4641. status: vue.unref(status).medalTasks.watch
  4642. }, null, 8, ["status"])
  4643. ]),
  4644. _: 1
  4645. })
  4646. ]),
  4647. _: 1
  4648. }),
  4649. vue.createVNode(_component_el_row, null, {
  4650. default: vue.withCtx(() => [
  4651. vue.createVNode(_component_el_space, {
  4652. wrap: "",
  4653. size: [8, 0]
  4654. }, {
  4655. default: vue.withCtx(() => [
  4656. vue.createVNode(_component_el_switch, {
  4657. modelValue: vue.unref(config).medalTasks.isWhiteList,
  4658. "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => vue.unref(config).medalTasks.isWhiteList = $event),
  4659. "active-text": "白名单",
  4660. "inactive-text": "黑名单",
  4661. onChange: _cache[7] || (_cache[7] = (val) => !val && (vue.unref(uiStore).uiConfig.medalInfoPanelSortMode = false))
  4662. }, null, 8, ["modelValue"]),
  4663. vue.createVNode(_component_el_button, {
  4664. type: "primary",
  4665. size: "small",
  4666. icon: vue.unref(ElementPlusIconsVue.Edit),
  4667. onClick: handleEditList
  4668. }, {
  4669. default: vue.withCtx(() => _cache[18] || (_cache[18] = [
  4670. vue.createTextVNode("编辑名单 ")
  4671. ])),
  4672. _: 1
  4673. }, 8, ["icon"]),
  4674. vue.createVNode(_component_Info, {
  4675. item: vue.unref(helpInfo).DailyTasks.LiveTasks.medalTasks.list
  4676. }, null, 8, ["item"])
  4677. ]),
  4678. _: 1
  4679. })
  4680. ]),
  4681. _: 1
  4682. }),
  4683. vue.createVNode(_component_el_divider),
  4684. vue.createVNode(_component_el_row, null, {
  4685. default: vue.withCtx(() => [
  4686. vue.createVNode(_component_el_text, null, {
  4687. default: vue.withCtx(() => _cache[19] || (_cache[19] = [
  4688. vue.createTextVNode("直播任务相关信息可在")
  4689. ])),
  4690. _: 1
  4691. }),
  4692. vue.createVNode(_component_el_link, {
  4693. rel: "noreferrer",
  4694. type: "primary",
  4695. href: "https://link.bilibili.com/p/help/index#/audience-fans-medal",
  4696. target: "_blank"
  4697. }, {
  4698. default: vue.withCtx(() => _cache[20] || (_cache[20] = [
  4699. vue.createTextVNode("帮助中心 ")
  4700. ])),
  4701. _: 1
  4702. }),
  4703. vue.createVNode(_component_el_text, null, {
  4704. default: vue.withCtx(() => _cache[21] || (_cache[21] = [
  4705. vue.createTextVNode("查看。")
  4706. ])),
  4707. _: 1
  4708. })
  4709. ]),
  4710. _: 1
  4711. }),
  4712. _cache[25] || (_cache[25] = vue.createElementVNode("br", null, null, -1)),
  4713. vue.createVNode(_component_el_dialog, {
  4714. modelValue: medalDanmuPanelVisible.value,
  4715. "onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => medalDanmuPanelVisible.value = $event),
  4716. title: "编辑弹幕内容",
  4717. "lock-scroll": false,
  4718. width: "40%"
  4719. }, {
  4720. footer: vue.withCtx(() => [
  4721. vue.createVNode(_component_el_button, {
  4722. type: "primary",
  4723. onClick: handleAddDanmu
  4724. }, {
  4725. default: vue.withCtx(() => _cache[24] || (_cache[24] = [
  4726. vue.createTextVNode("新增弹幕")
  4727. ])),
  4728. _: 1
  4729. })
  4730. ]),
  4731. default: vue.withCtx(() => [
  4732. vue.createVNode(vue.unref(ElementPlus.ElTable), {
  4733. data: danmuTableData.value,
  4734. "max-height": danmuTableMaxHeight
  4735. }, {
  4736. default: vue.withCtx(() => [
  4737. vue.createVNode(_component_el_table_column, {
  4738. type: "index",
  4739. width: "80"
  4740. }),
  4741. vue.createVNode(_component_el_table_column, {
  4742. prop: "content",
  4743. label: "弹幕内容"
  4744. }),
  4745. vue.createVNode(_component_el_table_column, {
  4746. label: "操作",
  4747. width: "220",
  4748. align: "center"
  4749. }, {
  4750. default: vue.withCtx((scope) => [
  4751. vue.createVNode(_component_el_button, {
  4752. text: "",
  4753. icon: vue.unref(ElementPlusIconsVue.Edit),
  4754. onClick: ($event) => handleEditDanmu(scope.$index, scope.row)
  4755. }, {
  4756. default: vue.withCtx(() => _cache[22] || (_cache[22] = [
  4757. vue.createTextVNode(" 修改 ")
  4758. ])),
  4759. _: 2
  4760. }, 1032, ["icon", "onClick"]),
  4761. vue.createVNode(_component_el_button, {
  4762. text: "",
  4763. icon: vue.unref(ElementPlusIconsVue.Delete),
  4764. type: "danger",
  4765. onClick: ($event) => handleDeleteDanmu(scope.$index)
  4766. }, {
  4767. default: vue.withCtx(() => _cache[23] || (_cache[23] = [
  4768. vue.createTextVNode(" 删除 ")
  4769. ])),
  4770. _: 2
  4771. }, 1032, ["icon", "onClick"])
  4772. ]),
  4773. _: 1
  4774. })
  4775. ]),
  4776. _: 1
  4777. }, 8, ["data"])
  4778. ]),
  4779. _: 1
  4780. }, 8, ["modelValue"]),
  4781. vue.createVNode(_component_el_dialog, {
  4782. modelValue: medalInfoPanelVisible.value,
  4783. "onUpdate:modelValue": _cache[13] || (_cache[13] = ($event) => medalInfoPanelVisible.value = $event),
  4784. title: "编辑粉丝勋章名单",
  4785. "lock-scroll": false
  4786. }, {
  4787. footer: vue.withCtx(() => [
  4788. vue.createVNode(_component_el_switch, {
  4789. disabled: !vue.unref(config).medalTasks.isWhiteList,
  4790. modelValue: vue.unref(uiStore).uiConfig.medalInfoPanelSortMode,
  4791. "onUpdate:modelValue": _cache[11] || (_cache[11] = ($event) => vue.unref(uiStore).uiConfig.medalInfoPanelSortMode = $event),
  4792. "inactive-text": "常规模式",
  4793. "active-text": "排序模式",
  4794. onChange: _cache[12] || (_cache[12] = (val) => !val && vue.nextTick(() => initSelection(medalInfoTableData.value)))
  4795. }, null, 8, ["disabled", "modelValue"])
  4796. ]),
  4797. default: vue.withCtx(() => [
  4798. vue.createVNode(vue.unref(vueDraggablePlus.VueDraggable), {
  4799. modelValue: medalInfoTableData.value,
  4800. "onUpdate:modelValue": _cache[10] || (_cache[10] = ($event) => medalInfoTableData.value = $event),
  4801. target: "#draggable-fans-medal-table table tbody",
  4802. disabled: !vue.unref(uiStore).uiConfig.medalInfoPanelSortMode,
  4803. animation: 150,
  4804. "scroll-sensitivity": 36,
  4805. "scroll-speed": 8
  4806. }, {
  4807. default: vue.withCtx(() => [
  4808. vue.withDirectives((vue.openBlock(), vue.createBlock(vue.unref(ElementPlus.ElTable), {
  4809. id: "draggable-fans-medal-table",
  4810. ref_key: "medalInfoTableRef",
  4811. ref: medalInfoTableRef,
  4812. data: medalInfoTableData.value,
  4813. "max-height": medalTableMaxHeight,
  4814. "empty-text": "没有粉丝勋章",
  4815. onSelect: handleSelect,
  4816. onSelectAll: handleSelect,
  4817. onRowClick: handleRowClick,
  4818. "row-key": (row) => row.roomid.toString()
  4819. }, {
  4820. default: vue.withCtx(() => [
  4821. !vue.unref(uiStore).uiConfig.medalInfoPanelSortMode ? (vue.openBlock(), vue.createBlock(_component_el_table_column, {
  4822. key: 0,
  4823. type: "selection",
  4824. align: "center",
  4825. width: "80"
  4826. })) : (vue.openBlock(), vue.createBlock(_component_el_table_column, {
  4827. key: 1,
  4828. type: "index",
  4829. align: "center",
  4830. width: "80"
  4831. })),
  4832. vue.createVNode(_component_el_table_column, {
  4833. prop: "avatar",
  4834. label: "头像",
  4835. width: "100"
  4836. }, {
  4837. default: vue.withCtx((scope) => [
  4838. vue.createElementVNode("div", _hoisted_1$1, [
  4839. vue.createVNode(_component_el_image, {
  4840. src: scope.row.avatar,
  4841. loading: "lazy",
  4842. referrerpolicy: "origin",
  4843. class: "avatar"
  4844. }, {
  4845. error: vue.withCtx(() => [
  4846. vue.createVNode(_component_el_image, {
  4847. src: "//i0.hdslb.com/bfs/face/member/noface.jpg",
  4848. referrerpolicy: "origin",
  4849. class: "avatar"
  4850. })
  4851. ]),
  4852. _: 2
  4853. }, 1032, ["src"])
  4854. ])
  4855. ]),
  4856. _: 1
  4857. }),
  4858. vue.createVNode(_component_el_table_column, {
  4859. prop: "nick_name",
  4860. label: "昵称"
  4861. }),
  4862. vue.createVNode(_component_el_table_column, {
  4863. prop: "medal_name",
  4864. label: "粉丝勋章"
  4865. }),
  4866. vue.createVNode(_component_el_table_column, {
  4867. prop: "medal_level",
  4868. label: "等级",
  4869. width: "80",
  4870. sortable: ""
  4871. }),
  4872. vue.createVNode(_component_el_table_column, {
  4873. prop: "roomid",
  4874. label: "房间号"
  4875. }, {
  4876. default: vue.withCtx((scope) => [
  4877. vue.createVNode(_component_el_link, {
  4878. href: "https://live.bilibili.com/" + scope.row.roomid + "?visit_id=",
  4879. rel: "noreferrer",
  4880. type: "primary",
  4881. target: "_blank",
  4882. onClick: _cache[9] || (_cache[9] = vue.withModifiers(() => {
  4883. }, ["stop"]))
  4884. }, {
  4885. default: vue.withCtx(() => [
  4886. vue.createTextVNode(vue.toDisplayString(scope.row.roomid), 1)
  4887. ]),
  4888. _: 2
  4889. }, 1032, ["href"])
  4890. ]),
  4891. _: 1
  4892. })
  4893. ]),
  4894. _: 1
  4895. }, 8, ["data", "row-key"])), [
  4896. [_directive_loading, medalInfoLoading.value]
  4897. ])
  4898. ]),
  4899. _: 1
  4900. }, 8, ["modelValue", "disabled"])
  4901. ]),
  4902. _: 1
  4903. }, 8, ["modelValue"])
  4904. ]);
  4905. };
  4906. }
  4907. });
  4908. const LiveTasks = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["__scopeId", "data-v-584fbcd9"]]);
  4909. const _sfc_main$8 = /* @__PURE__ */ vue.defineComponent({
  4910. __name: "OtherTasks",
  4911. setup(__props) {
  4912. const moduleStore2 = useModuleStore();
  4913. const config = moduleStore2.moduleConfig.DailyTasks.OtherTasks;
  4914. const status = moduleStore2.moduleStatus.DailyTasks.OtherTasks;
  4915. return (_ctx, _cache) => {
  4916. const _component_el_switch = vue.resolveComponent("el-switch");
  4917. const _component_Info = vue.resolveComponent("Info");
  4918. const _component_TaskStatus = vue.resolveComponent("TaskStatus");
  4919. const _component_el_space = vue.resolveComponent("el-space");
  4920. const _component_el_row = vue.resolveComponent("el-row");
  4921. const _component_el_text = vue.resolveComponent("el-text");
  4922. const _component_el_option = vue.resolveComponent("el-option");
  4923. const _component_el_select = vue.resolveComponent("el-select");
  4924. const _component_el_divider = vue.resolveComponent("el-divider");
  4925. return vue.openBlock(), vue.createElementBlock("div", null, [
  4926. vue.createVNode(_component_el_row, null, {
  4927. default: vue.withCtx(() => [
  4928. vue.createVNode(_component_el_space, { wrap: "" }, {
  4929. default: vue.withCtx(() => [
  4930. vue.createVNode(_component_el_switch, {
  4931. modelValue: vue.unref(config).groupSign.enabled,
  4932. "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => vue.unref(config).groupSign.enabled = $event),
  4933. "active-text": "应援团签到"
  4934. }, null, 8, ["modelValue"]),
  4935. vue.createVNode(_component_Info, {
  4936. item: vue.unref(helpInfo).DailyTasks.OtherTasks.groupSign
  4937. }, null, 8, ["item"]),
  4938. vue.createVNode(_component_TaskStatus, {
  4939. status: vue.unref(status).groupSign
  4940. }, null, 8, ["status"])
  4941. ]),
  4942. _: 1
  4943. })
  4944. ]),
  4945. _: 1
  4946. }),
  4947. vue.createVNode(_component_el_row, null, {
  4948. default: vue.withCtx(() => [
  4949. vue.createVNode(_component_el_space, { wrap: "" }, {
  4950. default: vue.withCtx(() => [
  4951. vue.createVNode(_component_el_switch, {
  4952. modelValue: vue.unref(config).silverToCoin.enabled,
  4953. "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => vue.unref(config).silverToCoin.enabled = $event),
  4954. "active-text": "银瓜子换硬币"
  4955. }, null, 8, ["modelValue"]),
  4956. vue.createVNode(_component_Info, {
  4957. item: vue.unref(helpInfo).DailyTasks.OtherTasks.silverToCoin
  4958. }, null, 8, ["item"]),
  4959. vue.createVNode(_component_TaskStatus, {
  4960. status: vue.unref(status).silverToCoin
  4961. }, null, 8, ["status"])
  4962. ]),
  4963. _: 1
  4964. })
  4965. ]),
  4966. _: 1
  4967. }),
  4968. vue.createVNode(_component_el_row, null, {
  4969. default: vue.withCtx(() => [
  4970. vue.createVNode(_component_el_space, {
  4971. wrap: "",
  4972. size: [8, 0]
  4973. }, {
  4974. default: vue.withCtx(() => [
  4975. vue.createVNode(_component_el_switch, {
  4976. modelValue: vue.unref(config).coinToSilver.enabled,
  4977. "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => vue.unref(config).coinToSilver.enabled = $event),
  4978. "active-text": "硬币换银瓜子"
  4979. }, null, 8, ["modelValue"]),
  4980. vue.createVNode(_component_el_text, null, {
  4981. default: vue.withCtx(() => _cache[5] || (_cache[5] = [
  4982. vue.createTextVNode("花费硬币")
  4983. ])),
  4984. _: 1
  4985. }),
  4986. vue.createVNode(_component_el_select, {
  4987. modelValue: vue.unref(config).coinToSilver.num,
  4988. "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => vue.unref(config).coinToSilver.num = $event),
  4989. placeholder: "Select",
  4990. style: { "width": "64px" }
  4991. }, {
  4992. default: vue.withCtx(() => [
  4993. (vue.openBlock(), vue.createElementBlock(vue.Fragment, null, vue.renderList(50, (i) => {
  4994. return vue.createVNode(_component_el_option, {
  4995. key: i,
  4996. label: i,
  4997. value: i
  4998. }, null, 8, ["label", "value"]);
  4999. }), 64))
  5000. ]),
  5001. _: 1
  5002. }, 8, ["modelValue"]),
  5003. vue.createVNode(_component_el_text, null, {
  5004. default: vue.withCtx(() => _cache[6] || (_cache[6] = [
  5005. vue.createTextVNode("个")
  5006. ])),
  5007. _: 1
  5008. }),
  5009. vue.createVNode(_component_Info, {
  5010. item: vue.unref(helpInfo).DailyTasks.OtherTasks.coinToSilver
  5011. }, null, 8, ["item"]),
  5012. vue.createVNode(_component_TaskStatus, {
  5013. status: vue.unref(status).coinToSilver
  5014. }, null, 8, ["status"])
  5015. ]),
  5016. _: 1
  5017. })
  5018. ]),
  5019. _: 1
  5020. }),
  5021. vue.createVNode(_component_el_row, null, {
  5022. default: vue.withCtx(() => [
  5023. vue.createVNode(_component_el_space, {
  5024. wrap: "",
  5025. size: [8, 0]
  5026. }, {
  5027. default: vue.withCtx(() => [
  5028. vue.createVNode(_component_el_switch, {
  5029. modelValue: vue.unref(config).getYearVipPrivilege.enabled,
  5030. "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => vue.unref(config).getYearVipPrivilege.enabled = $event),
  5031. "active-text": "领取年度大会员权益"
  5032. }, null, 8, ["modelValue"]),
  5033. vue.createVNode(_component_Info, {
  5034. item: vue.unref(helpInfo).DailyTasks.OtherTasks.getYearVipPrivilege
  5035. }, null, 8, ["item"]),
  5036. vue.createVNode(_component_TaskStatus, {
  5037. status: vue.unref(status).getYearVipPrivilege
  5038. }, null, 8, ["status"])
  5039. ]),
  5040. _: 1
  5041. })
  5042. ]),
  5043. _: 1
  5044. }),
  5045. vue.createVNode(_component_el_divider)
  5046. ]);
  5047. };
  5048. }
  5049. });
  5050. const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
  5051. __name: "EnhanceExperience",
  5052. setup(__props) {
  5053. const moduleStore2 = useModuleStore();
  5054. const config = moduleStore2.moduleConfig.EnhanceExperience;
  5055. const qualityDescList = ["原画", "蓝光PRO", "蓝光", "超清PRO", "超清", "高清"];
  5056. return (_ctx, _cache) => {
  5057. const _component_el_switch = vue.resolveComponent("el-switch");
  5058. const _component_el_option = vue.resolveComponent("el-option");
  5059. const _component_el_select = vue.resolveComponent("el-select");
  5060. const _component_Info = vue.resolveComponent("Info");
  5061. const _component_el_space = vue.resolveComponent("el-space");
  5062. const _component_el_row = vue.resolveComponent("el-row");
  5063. const _component_el_divider = vue.resolveComponent("el-divider");
  5064. return vue.openBlock(), vue.createElementBlock("div", null, [
  5065. vue.createVNode(_component_el_row, null, {
  5066. default: vue.withCtx(() => [
  5067. vue.createVNode(_component_el_space, {
  5068. wrap: "",
  5069. size: [8, 0]
  5070. }, {
  5071. default: vue.withCtx(() => [
  5072. vue.createVNode(_component_el_switch, {
  5073. modelValue: vue.unref(config).switchLiveStreamQuality.enabled,
  5074. "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => vue.unref(config).switchLiveStreamQuality.enabled = $event),
  5075. "active-text": "自动切换画质"
  5076. }, null, 8, ["modelValue"]),
  5077. vue.createVNode(_component_el_select, {
  5078. modelValue: vue.unref(config).switchLiveStreamQuality.qualityDesc,
  5079. "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => vue.unref(config).switchLiveStreamQuality.qualityDesc = $event),
  5080. placeholder: "Select",
  5081. style: { "width": "110px" }
  5082. }, {
  5083. default: vue.withCtx(() => [
  5084. (vue.openBlock(), vue.createElementBlock(vue.Fragment, null, vue.renderList(qualityDescList, (i) => {
  5085. return vue.createVNode(_component_el_option, {
  5086. key: i,
  5087. label: i,
  5088. value: i
  5089. }, null, 8, ["label", "value"]);
  5090. }), 64))
  5091. ]),
  5092. _: 1
  5093. }, 8, ["modelValue"]),
  5094. vue.createVNode(_component_Info, {
  5095. item: vue.unref(helpInfo).EnhanceExperience.switchLiveStreamQuality
  5096. }, null, 8, ["item"])
  5097. ]),
  5098. _: 1
  5099. })
  5100. ]),
  5101. _: 1
  5102. }),
  5103. vue.createVNode(_component_el_row, null, {
  5104. default: vue.withCtx(() => [
  5105. vue.createVNode(_component_el_space, {
  5106. wrap: "",
  5107. size: [8, 0]
  5108. }, {
  5109. default: vue.withCtx(() => [
  5110. vue.createVNode(_component_el_switch, {
  5111. modelValue: vue.unref(config).banp2p.enabled,
  5112. "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => vue.unref(config).banp2p.enabled = $event),
  5113. "active-text": "禁用P2P"
  5114. }, null, 8, ["modelValue"]),
  5115. vue.createVNode(_component_Info, {
  5116. item: vue.unref(helpInfo).EnhanceExperience.banp2p
  5117. }, null, 8, ["item"])
  5118. ]),
  5119. _: 1
  5120. })
  5121. ]),
  5122. _: 1
  5123. }),
  5124. vue.createVNode(_component_el_row, null, {
  5125. default: vue.withCtx(() => [
  5126. vue.createVNode(_component_el_space, {
  5127. wrap: "",
  5128. size: [8, 0]
  5129. }, {
  5130. default: vue.withCtx(() => [
  5131. vue.createVNode(_component_el_switch, {
  5132. modelValue: vue.unref(config).noReport.enabled,
  5133. "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => vue.unref(config).noReport.enabled = $event),
  5134. "active-text": "拦截日志数据上报"
  5135. }, null, 8, ["modelValue"]),
  5136. vue.createVNode(_component_Info, {
  5137. item: vue.unref(helpInfo).EnhanceExperience.noReport
  5138. }, null, 8, ["item"])
  5139. ]),
  5140. _: 1
  5141. })
  5142. ]),
  5143. _: 1
  5144. }),
  5145. vue.createVNode(_component_el_row, null, {
  5146. default: vue.withCtx(() => [
  5147. vue.createVNode(_component_el_space, {
  5148. wrap: "",
  5149. size: [8, 0]
  5150. }, {
  5151. default: vue.withCtx(() => [
  5152. vue.createVNode(_component_el_switch, {
  5153. modelValue: vue.unref(config).noSleep.enabled,
  5154. "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => vue.unref(config).noSleep.enabled = $event),
  5155. "active-text": "屏蔽挂机检测"
  5156. }, null, 8, ["modelValue"]),
  5157. vue.createVNode(_component_Info, {
  5158. item: vue.unref(helpInfo).EnhanceExperience.noSleep
  5159. }, null, 8, ["item"])
  5160. ]),
  5161. _: 1
  5162. })
  5163. ]),
  5164. _: 1
  5165. }),
  5166. vue.createVNode(_component_el_row, null, {
  5167. default: vue.withCtx(() => [
  5168. vue.createVNode(_component_el_space, {
  5169. wrap: "",
  5170. size: [8, 0]
  5171. }, {
  5172. default: vue.withCtx(() => [
  5173. vue.createVNode(_component_el_switch, {
  5174. modelValue: vue.unref(config).invisibility.enabled,
  5175. "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => vue.unref(config).invisibility.enabled = $event),
  5176. "active-text": "隐身入场"
  5177. }, null, 8, ["modelValue"]),
  5178. vue.createVNode(_component_Info, {
  5179. item: vue.unref(helpInfo).EnhanceExperience.invisibility
  5180. }, null, 8, ["item"])
  5181. ]),
  5182. _: 1
  5183. })
  5184. ]),
  5185. _: 1
  5186. }),
  5187. vue.createVNode(_component_el_divider)
  5188. ]);
  5189. };
  5190. }
  5191. });
  5192. const _sfc_main$6 = /* @__PURE__ */ vue.defineComponent({
  5193. __name: "RemoveElement",
  5194. setup(__props) {
  5195. const moduleStore2 = useModuleStore();
  5196. const config = moduleStore2.moduleConfig.RemoveElement;
  5197. return (_ctx, _cache) => {
  5198. const _component_el_switch = vue.resolveComponent("el-switch");
  5199. const _component_Info = vue.resolveComponent("Info");
  5200. const _component_el_space = vue.resolveComponent("el-space");
  5201. const _component_el_row = vue.resolveComponent("el-row");
  5202. const _component_el_divider = vue.resolveComponent("el-divider");
  5203. return vue.openBlock(), vue.createElementBlock("div", null, [
  5204. vue.createVNode(_component_el_row, null, {
  5205. default: vue.withCtx(() => [
  5206. vue.createVNode(_component_el_space, {
  5207. wrap: "",
  5208. size: [8, 0]
  5209. }, {
  5210. default: vue.withCtx(() => [
  5211. vue.createVNode(_component_el_switch, {
  5212. modelValue: vue.unref(config).removePKBox.enabled,
  5213. "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => vue.unref(config).removePKBox.enabled = $event),
  5214. "active-text": "移除大乱斗元素"
  5215. }, null, 8, ["modelValue"]),
  5216. vue.createVNode(_component_Info, {
  5217. item: vue.unref(helpInfo).RemoveElement.removePKBox
  5218. }, null, 8, ["item"])
  5219. ]),
  5220. _: 1
  5221. })
  5222. ]),
  5223. _: 1
  5224. }),
  5225. vue.createVNode(_component_el_row, null, {
  5226. default: vue.withCtx(() => [
  5227. vue.createVNode(_component_el_space, {
  5228. wrap: "",
  5229. size: [8, 0]
  5230. }, {
  5231. default: vue.withCtx(() => [
  5232. vue.createVNode(_component_el_switch, {
  5233. modelValue: vue.unref(config).removeLiveWaterMark.enabled,
  5234. "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => vue.unref(config).removeLiveWaterMark.enabled = $event),
  5235. "active-text": "移除直播间水印"
  5236. }, null, 8, ["modelValue"]),
  5237. vue.createVNode(_component_Info, {
  5238. item: vue.unref(helpInfo).RemoveElement.removeLiveWaterMark
  5239. }, null, 8, ["item"])
  5240. ]),
  5241. _: 1
  5242. })
  5243. ]),
  5244. _: 1
  5245. }),
  5246. vue.createVNode(_component_el_row, null, {
  5247. default: vue.withCtx(() => [
  5248. vue.createVNode(_component_el_space, {
  5249. wrap: "",
  5250. size: [8, 0]
  5251. }, {
  5252. default: vue.withCtx(() => [
  5253. vue.createVNode(_component_el_switch, {
  5254. modelValue: vue.unref(config).removeShopPopover.enabled,
  5255. "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => vue.unref(config).removeShopPopover.enabled = $event),
  5256. "active-text": "移除直播间小橙车弹窗"
  5257. }, null, 8, ["modelValue"]),
  5258. vue.createVNode(_component_Info, {
  5259. item: vue.unref(helpInfo).RemoveElement.removeShopPopover
  5260. }, null, 8, ["item"])
  5261. ]),
  5262. _: 1
  5263. })
  5264. ]),
  5265. _: 1
  5266. }),
  5267. vue.createVNode(_component_el_row, null, {
  5268. default: vue.withCtx(() => [
  5269. vue.createVNode(_component_el_space, {
  5270. wrap: "",
  5271. size: [8, 0]
  5272. }, {
  5273. default: vue.withCtx(() => [
  5274. vue.createVNode(_component_el_switch, {
  5275. modelValue: vue.unref(config).removeGameParty.enabled,
  5276. "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => vue.unref(config).removeGameParty.enabled = $event),
  5277. "active-text": "移除直播间幻星派对标志"
  5278. }, null, 8, ["modelValue"]),
  5279. vue.createVNode(_component_Info, {
  5280. item: vue.unref(helpInfo).RemoveElement.removeGameParty
  5281. }, null, 8, ["item"])
  5282. ]),
  5283. _: 1
  5284. })
  5285. ]),
  5286. _: 1
  5287. }),
  5288. vue.createVNode(_component_el_row, null, {
  5289. default: vue.withCtx(() => [
  5290. vue.createVNode(_component_el_space, {
  5291. wrap: "",
  5292. size: [8, 0]
  5293. }, {
  5294. default: vue.withCtx(() => [
  5295. vue.createVNode(_component_el_switch, {
  5296. modelValue: vue.unref(config).removeGiftPopover.enabled,
  5297. "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => vue.unref(config).removeGiftPopover.enabled = $event),
  5298. "active-text": "移除礼物赠送提示弹窗"
  5299. }, null, 8, ["modelValue"]),
  5300. vue.createVNode(_component_Info, {
  5301. item: vue.unref(helpInfo).RemoveElement.removeGiftPopover
  5302. }, null, 8, ["item"])
  5303. ]),
  5304. _: 1
  5305. })
  5306. ]),
  5307. _: 1
  5308. }),
  5309. vue.createVNode(_component_el_row, null, {
  5310. default: vue.withCtx(() => [
  5311. vue.createVNode(_component_el_space, {
  5312. wrap: "",
  5313. size: [8, 0]
  5314. }, {
  5315. default: vue.withCtx(() => [
  5316. vue.createVNode(_component_el_switch, {
  5317. modelValue: vue.unref(config).removeMicPopover.enabled,
  5318. "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => vue.unref(config).removeMicPopover.enabled = $event),
  5319. "active-text": "移除连麦状态提示"
  5320. }, null, 8, ["modelValue"]),
  5321. vue.createVNode(_component_Info, {
  5322. item: vue.unref(helpInfo).RemoveElement.removeMicPopover
  5323. }, null, 8, ["item"])
  5324. ]),
  5325. _: 1
  5326. })
  5327. ]),
  5328. _: 1
  5329. }),
  5330. vue.createVNode(_component_el_row, null, {
  5331. default: vue.withCtx(() => [
  5332. vue.createVNode(_component_el_space, {
  5333. wrap: "",
  5334. size: [8, 0]
  5335. }, {
  5336. default: vue.withCtx(() => [
  5337. vue.createVNode(_component_el_switch, {
  5338. modelValue: vue.unref(config).removeComboCard.enabled,
  5339. "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => vue.unref(config).removeComboCard.enabled = $event),
  5340. "active-text": "移除直播间相同弹幕连续提示"
  5341. }, null, 8, ["modelValue"]),
  5342. vue.createVNode(_component_Info, {
  5343. item: vue.unref(helpInfo).RemoveElement.removeComboCard
  5344. }, null, 8, ["item"])
  5345. ]),
  5346. _: 1
  5347. })
  5348. ]),
  5349. _: 1
  5350. }),
  5351. vue.createVNode(_component_el_row, null, {
  5352. default: vue.withCtx(() => [
  5353. vue.createVNode(_component_el_space, {
  5354. wrap: "",
  5355. size: [8, 0]
  5356. }, {
  5357. default: vue.withCtx(() => [
  5358. vue.createVNode(_component_el_switch, {
  5359. modelValue: vue.unref(config).removeRank.enabled,
  5360. "onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => vue.unref(config).removeRank.enabled = $event),
  5361. "active-text": "移除排行榜"
  5362. }, null, 8, ["modelValue"]),
  5363. vue.createVNode(_component_Info, {
  5364. item: vue.unref(helpInfo).RemoveElement.removeRank
  5365. }, null, 8, ["item"])
  5366. ]),
  5367. _: 1
  5368. })
  5369. ]),
  5370. _: 1
  5371. }),
  5372. vue.createVNode(_component_el_row, null, {
  5373. default: vue.withCtx(() => [
  5374. vue.createVNode(_component_el_space, {
  5375. wrap: "",
  5376. size: [8, 0]
  5377. }, {
  5378. default: vue.withCtx(() => [
  5379. vue.createVNode(_component_el_switch, {
  5380. modelValue: vue.unref(config).removeHeaderStuff.enabled,
  5381. "onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => vue.unref(config).removeHeaderStuff.enabled = $event),
  5382. "active-text": "移除直播画面上方杂项"
  5383. }, null, 8, ["modelValue"]),
  5384. vue.createVNode(_component_Info, {
  5385. item: vue.unref(helpInfo).RemoveElement.removeHeaderStuff
  5386. }, null, 8, ["item"])
  5387. ]),
  5388. _: 1
  5389. })
  5390. ]),
  5391. _: 1
  5392. }),
  5393. vue.createVNode(_component_el_row, null, {
  5394. default: vue.withCtx(() => [
  5395. vue.createVNode(_component_el_space, {
  5396. wrap: "",
  5397. size: [8, 0]
  5398. }, {
  5399. default: vue.withCtx(() => [
  5400. vue.createVNode(_component_el_switch, {
  5401. modelValue: vue.unref(config).removeFlipView.enabled,
  5402. "onUpdate:modelValue": _cache[9] || (_cache[9] = ($event) => vue.unref(config).removeFlipView.enabled = $event),
  5403. "active-text": "移除礼物栏下方广告"
  5404. }, null, 8, ["modelValue"]),
  5405. vue.createVNode(_component_Info, {
  5406. item: vue.unref(helpInfo).RemoveElement.removeFlipView
  5407. }, null, 8, ["item"])
  5408. ]),
  5409. _: 1
  5410. })
  5411. ]),
  5412. _: 1
  5413. }),
  5414. vue.createVNode(_component_el_row, null, {
  5415. default: vue.withCtx(() => [
  5416. vue.createVNode(_component_el_space, { "wrap:size": "[8, 0]" }, {
  5417. default: vue.withCtx(() => [
  5418. vue.createVNode(_component_el_switch, {
  5419. modelValue: vue.unref(config).removeRecommendRoom.enabled,
  5420. "onUpdate:modelValue": _cache[10] || (_cache[10] = ($event) => vue.unref(config).removeRecommendRoom.enabled = $event),
  5421. "active-text": "移除礼物栏下方推荐直播间"
  5422. }, null, 8, ["modelValue"]),
  5423. vue.createVNode(_component_Info, {
  5424. item: vue.unref(helpInfo).RemoveElement.removeRecommendRoom
  5425. }, null, 8, ["item"])
  5426. ]),
  5427. _: 1
  5428. })
  5429. ]),
  5430. _: 1
  5431. }),
  5432. vue.createVNode(_component_el_row, null, {
  5433. default: vue.withCtx(() => [
  5434. vue.createVNode(_component_el_space, {
  5435. wrap: "",
  5436. size: [8, 0]
  5437. }, {
  5438. default: vue.withCtx(() => [
  5439. vue.createVNode(_component_el_switch, {
  5440. modelValue: vue.unref(config).removeLiveMosaic.enabled,
  5441. "onUpdate:modelValue": _cache[11] || (_cache[11] = ($event) => vue.unref(config).removeLiveMosaic.enabled = $event),
  5442. "active-text": "移除直播间马赛克"
  5443. }, null, 8, ["modelValue"]),
  5444. vue.createVNode(_component_Info, {
  5445. item: vue.unref(helpInfo).RemoveElement.removeLiveMosaic
  5446. }, null, 8, ["item"])
  5447. ]),
  5448. _: 1
  5449. })
  5450. ]),
  5451. _: 1
  5452. }),
  5453. vue.createVNode(_component_el_divider)
  5454. ]);
  5455. };
  5456. }
  5457. });
  5458. const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
  5459. __name: "ScriptSettings",
  5460. setup(__props) {
  5461. const uiConfig = useUIStore().uiConfig;
  5462. return (_ctx, _cache) => {
  5463. const _component_el_text = vue.resolveComponent("el-text");
  5464. const _component_el_slider = vue.resolveComponent("el-slider");
  5465. const _component_el_space = vue.resolveComponent("el-space");
  5466. const _component_el_row = vue.resolveComponent("el-row");
  5467. return vue.openBlock(), vue.createElementBlock("div", null, [
  5468. vue.createVNode(_component_el_row, { align: "middle" }, {
  5469. default: vue.withCtx(() => [
  5470. vue.createVNode(_component_el_space, {
  5471. wrap: "",
  5472. size: [16, 0]
  5473. }, {
  5474. default: vue.withCtx(() => [
  5475. vue.createVNode(_component_el_text, { class: "label-text" }, {
  5476. default: vue.withCtx(() => _cache[1] || (_cache[1] = [
  5477. vue.createTextVNode("控制面板宽度")
  5478. ])),
  5479. _: 1
  5480. }),
  5481. vue.createVNode(_component_el_slider, {
  5482. style: { "width": "150px" },
  5483. class: "slider",
  5484. modelValue: vue.unref(uiConfig).panelWidthPercent,
  5485. "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => vue.unref(uiConfig).panelWidthPercent = $event),
  5486. min: 30,
  5487. max: 60
  5488. }, null, 8, ["modelValue"])
  5489. ]),
  5490. _: 1
  5491. })
  5492. ]),
  5493. _: 1
  5494. })
  5495. ]);
  5496. };
  5497. }
  5498. });
  5499. const ScriptSettings = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-1cb0d081"]]);
  5500. const __default__ = vue.defineComponent({
  5501. components: {
  5502. MainSiteTasks: _sfc_main$a,
  5503. LiveTasks,
  5504. OtherTasks: _sfc_main$8,
  5505. EnhanceExperience: _sfc_main$7,
  5506. RemoveElement: _sfc_main$6,
  5507. ScriptSettings
  5508. }
  5509. });
  5510. const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
  5511. ...__default__,
  5512. __name: "PanelMain",
  5513. setup(__props) {
  5514. const uiStore = useUIStore();
  5515. return (_ctx, _cache) => {
  5516. return vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(vue.unref(uiStore).uiConfig.activeMenuIndex));
  5517. };
  5518. }
  5519. });
  5520. const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
  5521. __name: "App",
  5522. setup(__props) {
  5523. const uiStore = useUIStore();
  5524. const logger2 = new Logger("App.vue");
  5525. let isShowPanel = uiStore.uiConfig.isShowPanel;
  5526. uiStore.uiConfig.isShowPanel = false;
  5527. let livePlayer;
  5528. let button;
  5529. function updatePosition() {
  5530. const rect = livePlayer.getBoundingClientRect();
  5531. uiStore.livePlayerRect.top = rect.top;
  5532. uiStore.livePlayerRect.left = rect.left;
  5533. uiStore.livePlayerRect.height = rect.height;
  5534. uiStore.livePlayerRect.width = rect.width;
  5535. uiStore.windowScrollPosition.x = _unsafeWindow.scrollX;
  5536. uiStore.windowScrollPosition.y = _unsafeWindow.scrollY;
  5537. }
  5538. function buttonOnClick() {
  5539. uiStore.changeShowPanel();
  5540. button.innerText = uiStore.isShowPanelButtonText;
  5541. }
  5542. const throttleButtonOnClick = _.throttle(buttonOnClick, 300);
  5543. livePlayer = dq("#live-player-ctnr");
  5544. if (livePlayer) {
  5545. updatePosition();
  5546. waitForElement(dq("#player-ctnr"), ".left-ctnr.left-header-area", 1e4).then((playerHeaderLeft) => {
  5547. button = dce("button");
  5548. button.setAttribute("class", "blth_btn");
  5549. button.onclick = throttleButtonOnClick;
  5550. button.innerText = uiStore.isShowPanelButtonText;
  5551. playerHeaderLeft.append(button);
  5552. if (!isSelfTopFrame()) {
  5553. hotkeys(
  5554. "alt+b",
  5555. {
  5556. element: topFrameDocumentElement()
  5557. },
  5558. throttleButtonOnClick
  5559. );
  5560. }
  5561. hotkeys("alt+b", throttleButtonOnClick);
  5562. }).catch((e) => logger2.error(e));
  5563. window.addEventListener("resize", () => updatePosition());
  5564. const observer = new MutationObserver(() => updatePosition());
  5565. observer.observe(document.body, { attributes: true });
  5566. observer.observe(document.documentElement, { attributes: true });
  5567. if (isShowPanel) {
  5568. uiStore.uiConfig.isShowPanel = true;
  5569. }
  5570. } else {
  5571. logger2.error("livePlayer not found");
  5572. }
  5573. return (_ctx, _cache) => {
  5574. const _component_el_header = vue.resolveComponent("el-header");
  5575. const _component_el_aside = vue.resolveComponent("el-aside");
  5576. const _component_el_scrollbar = vue.resolveComponent("el-scrollbar");
  5577. const _component_el_main = vue.resolveComponent("el-main");
  5578. const _component_el_container = vue.resolveComponent("el-container");
  5579. const _component_el_collapse_transition = vue.resolveComponent("el-collapse-transition");
  5580. return vue.openBlock(), vue.createBlock(_component_el_collapse_transition, null, {
  5581. default: vue.withCtx(() => [
  5582. vue.withDirectives(vue.createVNode(_component_el_container, {
  5583. style: vue.normalizeStyle(vue.unref(uiStore).panelStyle),
  5584. class: "base"
  5585. }, {
  5586. default: vue.withCtx(() => [
  5587. vue.createVNode(_component_el_header, { class: "header" }, {
  5588. default: vue.withCtx(() => [
  5589. vue.createVNode(PanelHeader)
  5590. ]),
  5591. _: 1
  5592. }),
  5593. vue.createVNode(_component_el_container, null, {
  5594. default: vue.withCtx(() => [
  5595. vue.createVNode(_component_el_aside, { class: "aside" }, {
  5596. default: vue.withCtx(() => [
  5597. vue.createVNode(PanelAside)
  5598. ]),
  5599. _: 1
  5600. }),
  5601. vue.createVNode(_component_el_main, { class: "main" }, {
  5602. default: vue.withCtx(() => [
  5603. vue.createVNode(_component_el_scrollbar, {
  5604. height: vue.unref(uiStore).scrollBarHeight
  5605. }, {
  5606. default: vue.withCtx(() => [
  5607. (vue.openBlock(), vue.createBlock(vue.KeepAlive, null, [
  5608. vue.createVNode(vue.Transition, {
  5609. name: "fade",
  5610. mode: "out-in"
  5611. }, {
  5612. default: vue.withCtx(() => [
  5613. vue.createVNode(_sfc_main$4)
  5614. ]),
  5615. _: 1
  5616. })
  5617. ], 1024))
  5618. ]),
  5619. _: 1
  5620. }, 8, ["height"])
  5621. ]),
  5622. _: 1
  5623. })
  5624. ]),
  5625. _: 1
  5626. })
  5627. ]),
  5628. _: 1
  5629. }, 8, ["style"]), [
  5630. [vue.vShow, vue.unref(uiStore).uiConfig.isShowPanel]
  5631. ])
  5632. ]),
  5633. _: 1
  5634. });
  5635. };
  5636. }
  5637. });
  5638. const App = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-24895187"]]);
  5639. const cssLoader = (e) => {
  5640. const t = GM_getResourceText(e);
  5641. return GM_addStyle(t), t;
  5642. };
  5643. cssLoader("element-plus/dist/index.css");
  5644. const _sfc_main$2 = {};
  5645. const _hoisted_1 = {
  5646. xmlns: "http://www.w3.org/2000/svg",
  5647. width: "128",
  5648. height: "128",
  5649. class: "icon",
  5650. viewBox: "0 0 1024 1024"
  5651. };
  5652. function _sfc_render(_ctx, _cache) {
  5653. return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1, _cache[0] || (_cache[0] = [
  5654. vue.createElementVNode("path", { d: "M831.825 63.94H191.94c-70.692 0-128 57.308-128 128v639.885c0 70.692 57.308 128 128 128h639.885c70.692 0 128-57.308 128-128V191.94c0-70.692-57.308-128-128-128zM895.885 832a63.835 63.835 0 0 1-63.973 63.886H192.088c-17.112 0-33.27-6.575-45.372-18.676S127.88 849.112 127.88 832V192a64.236 64.236 0 0 1 64.208-64.12h639.824A64.038 64.038 0 0 1 895.885 192v640z" }, null, -1),
  5655. vue.createElementVNode("path", { d: "M791.998 351.852H536a31.97 31.97 0 0 0 0 63.94h256a31.97 31.97 0 0 0 0-63.94zm0 256.121H536a31.97 31.97 0 0 0 0 63.94h256a31.97 31.97 0 0 0 0-63.94zm-447.996-79.975c-61.856 0-111.986 50.144-111.986 111.985S282.16 751.97 344.002 751.97s111.985-50.144 111.985-111.986-50.13-111.985-111.985-111.985zm33.982 145.982a48.045 48.045 0 1 1 14.088-33.982 47.746 47.746 0 0 1-14.088 33.986zm39.412-376.586L311.999 402.787l-41.391-41.395a31.97 31.97 0 1 0-45.213 45.213l63.997 64.002a31.97 31.97 0 0 0 45.214 0l128-128a31.97 31.97 0 0 0-45.21-45.213z" }, null, -1)
  5656. ]));
  5657. }
  5658. const TasksIcon = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render]]);
  5659. const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
  5660. __name: "InfoIcon",
  5661. props: {
  5662. item: {}
  5663. },
  5664. setup(__props) {
  5665. const props = __props;
  5666. const open = () => {
  5667. const { title, message } = props.item;
  5668. ElementPlus.ElMessageBox({
  5669. title,
  5670. message,
  5671. lockScroll: false,
  5672. autofocus: true,
  5673. confirmButtonText: "OK"
  5674. }).catch(() => {
  5675. });
  5676. };
  5677. return (_ctx, _cache) => {
  5678. const _component_el_icon = vue.resolveComponent("el-icon");
  5679. return vue.openBlock(), vue.createBlock(_component_el_icon, {
  5680. class: "info-icon",
  5681. onClick: open
  5682. }, {
  5683. default: vue.withCtx(() => _cache[0] || (_cache[0] = [
  5684. vue.createElementVNode("svg", {
  5685. xmlns: "http://www.w3.org/2000/svg",
  5686. width: "128",
  5687. height: "128",
  5688. class: "icon",
  5689. viewBox: "0 0 1024 1024"
  5690. }, [
  5691. vue.createElementVNode("path", {
  5692. fill: "#276BC0",
  5693. d: "M512.67 959.47c-246.343 0-446.76-200.632-446.76-447.24S266.326 64.98 512.67 64.98s446.76 200.642 446.76 447.25-200.416 447.24-446.76 447.24zm0-829.04c-210.291 0-381.38 171.283-381.38 381.8s171.089 381.79 381.38 381.79 381.381-171.273 381.381-381.79-171.09-381.8-381.38-381.8z"
  5694. }),
  5695. vue.createElementVNode("path", {
  5696. fill: "#276BC0",
  5697. d: "M447.29 317.172a63.891 63.959 0 1 0 130.76 0 63.891 63.959 0 1 0-130.76 0Zm64.907 503.047c-30.093 0-54.235-24.416-54.235-54.541V482.062c0-30.126 24.142-54.541 54.235-54.541 30.094 0 54.236 24.416 54.236 54.541v283.616c0 30.125-24.142 54.54-54.236 54.54z"
  5698. })
  5699. ], -1)
  5700. ])),
  5701. _: 1
  5702. });
  5703. };
  5704. }
  5705. });
  5706. const InfoIcon = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-38289ed3"]]);
  5707. const _sfc_main = /* @__PURE__ */ vue.defineComponent({
  5708. __name: "TaskStatusIcon",
  5709. props: {
  5710. status: {}
  5711. },
  5712. setup(__props) {
  5713. return (_ctx, _cache) => {
  5714. const _component_Loading = vue.resolveComponent("Loading");
  5715. const _component_el_icon = vue.resolveComponent("el-icon");
  5716. const _component_Select = vue.resolveComponent("Select");
  5717. const _component_CloseBold = vue.resolveComponent("CloseBold");
  5718. return _ctx.status === "running" ? (vue.openBlock(), vue.createBlock(_component_el_icon, {
  5719. key: 0,
  5720. class: "status-icon is-loading"
  5721. }, {
  5722. default: vue.withCtx(() => [
  5723. vue.createVNode(_component_Loading)
  5724. ]),
  5725. _: 1
  5726. })) : _ctx.status === "done" ? (vue.openBlock(), vue.createBlock(_component_el_icon, {
  5727. key: 1,
  5728. class: "status-icon",
  5729. style: { "color": "#1ab059" }
  5730. }, {
  5731. default: vue.withCtx(() => [
  5732. vue.createVNode(_component_Select)
  5733. ]),
  5734. _: 1
  5735. })) : _ctx.status === "error" ? (vue.openBlock(), vue.createBlock(_component_el_icon, {
  5736. key: 2,
  5737. class: "status-icon",
  5738. style: { "color": "#ff6464" }
  5739. }, {
  5740. default: vue.withCtx(() => [
  5741. vue.createVNode(_component_CloseBold)
  5742. ]),
  5743. _: 1
  5744. })) : vue.createCommentVNode("", true);
  5745. };
  5746. }
  5747. });
  5748. const TaskStatusIcon = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-b4254e0f"]]);
  5749. const MyIconsVue = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  5750. __proto__: null,
  5751. Info: InfoIcon,
  5752. TaskStatus: TaskStatusIcon,
  5753. Tasks: TasksIcon
  5754. }, Symbol.toStringTag, { value: "Module" }));
  5755. const logger = new Logger("Main");
  5756. logger.log("document.readyState", document.readyState);
  5757. const pinia = pinia$1.createPinia();
  5758. const cacheStore = useCacheStore(pinia);
  5759. const moduleStore = useModuleStore(pinia);
  5760. cacheStore.checkCurrentScriptType();
  5761. logger.log("当前脚本的类型为", cacheStore.currentScriptType);
  5762. if (cacheStore.currentScriptType === "Main") {
  5763. cacheStore.startMainBLTHAliveHeartBeat();
  5764. }
  5765. moduleStore.loadModules("unknown");
  5766. await( waitForMoment("document-body"));
  5767. if (isTargetFrame()) {
  5768. const app = vue.createApp(App);
  5769. app.use(ElementPlus);
  5770. app.use(pinia);
  5771. for (const [key, component] of Object.entries(ElementPlusIconsVue__namespace)) {
  5772. app.component(key, component);
  5773. }
  5774. for (const [key, component] of Object.entries(MyIconsVue)) {
  5775. app.component(key, component);
  5776. }
  5777. moduleStore.loadModules("yes");
  5778. await( waitForMoment("document-end"));
  5779. const div = dce("div");
  5780. div.id = "BLTH";
  5781. document.body.append(div);
  5782. app.mount(div);
  5783. }
  5784.  
  5785. })(Vue, Pinia, _, ElementPlusIconsVue, CryptoJS, luxon, ElementPlus, VueDraggablePlus, hotkeys);

QingJ © 2025

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