播鸭功能扩展

播鸭播放器功能扩展集合

  1. // ==UserScript==
  2. // @name 播鸭功能扩展
  3. // @namespace web_chaser
  4. // @version 0.5
  5. // @description 播鸭播放器功能扩展集合
  6. // @note 我的播鸭 - 新增根据头像ID搜索用户名称
  7. // @note 播鸭签到 - 新增自动签到功能
  8. // @author web_chaser
  9. // @match https://boya.maiyuan.online/*
  10. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  11. // @grant none
  12. // @update https://gitee.com/web_chaser/search-user-name/blob/master/boya.js
  13. // @license Mozilla Public License 1.1 (MPL)
  14. // ==/UserScript==
  15.  
  16. (function () {
  17. 'use strict';
  18.  
  19. // 令牌
  20. const Token = JSON.parse(localStorage._boya_user_token)[0];
  21. // 判断是否有token令牌
  22. if (!Token) return;
  23.  
  24. // 形象商店数据容器
  25. let allCommoditiesArray = [];
  26.  
  27. // 域名
  28. const URL = 'https://boya.maiyuan.online/graphql';
  29. // 形象商店数据接口请求参数
  30. const commoditieInterface = {
  31. "operationName": "allCommodities",
  32. "variables": {
  33. "input": {
  34. "type": 2,
  35. "order": {
  36. "price": 0
  37. }
  38. }
  39. },
  40. "query": "query allCommodities($input: allCommoditiesInput!) {\n allCommodities(input: $input) {\n totalCount\n nodes {\n code\n image\n id\n introduction\n originalPrice\n price\n sales\n status\n stock\n title\n releaseTime\n createdAt\n user {\n id\n avatar\n name\n __typename\n }\n __typename\n }\n __typename\n }\n}\n"
  41. }
  42.  
  43. // 首次加载触发初始化
  44. window.onload = init;
  45.  
  46. // 初始化
  47. function init() {
  48. // 请求头像数据
  49. getAllCommodities(URL, commoditieInterface);
  50. // 新增搜索按钮
  51. createButton();
  52. };
  53.  
  54. // 请求数据
  55. async function getAllCommodities(url, data) {
  56. try {
  57. const result = await request(url, data);
  58. if (result.data) {
  59. allCommoditiesArray = result.data.allCommodities.nodes;
  60. }
  61. } catch {
  62. console.log('插件出问题啦~');
  63. };
  64. };
  65.  
  66. // 新增搜索按钮方法
  67. function createButton() {
  68. // 图标
  69. const sreachIcon = '<span role="img" class="anticon"><svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><use xlink:href="#icon-search"></use></svg></span>';
  70. // 创建按钮
  71. const buttonDom = document.createElement('button');
  72. buttonDom.innerHTML = sreachIcon;
  73. // 添加样式
  74. buttonDom.style.cssText = `
  75. background-color: rgb(94, 203, 87);
  76. color: rgb(255, 255, 255);
  77. width: 30px;
  78. height: 30px;
  79. border-radius: 6px;
  80. margin-left: 5px;
  81. font-size: 24px;
  82. line-height: 24px;
  83. box-shadow: rgba(94, 203, 87, 0.6) 0px 2px 6px 0px;
  84. position: relative;
  85. `;
  86. const inputDom = document.querySelector('.ant-input-affix-wrapper').children[0];
  87. inputDom.placeholder = '请输入歌曲、艺人、专辑 / 头像ID编号';
  88. // 添加按钮点击事件
  89. buttonDom.addEventListener('click', () => {
  90. searchUserCode(inputDom.value);
  91. document.querySelector('.ant-input-clear-icon').click(); // 触发清空事件
  92. });
  93. // 加入按钮组父级容器
  94. pollingHandle(buttonDom);
  95. };
  96.  
  97. // 获取按钮组父级容器 切换路由可能导致组件未渲染而获取null
  98. function pollingHandle(buttonDom) {
  99. const className = 'middle-wrap___2XeZY';
  100. // 获取按钮组父级容器
  101. const parent = document.querySelector(`.${className}`);
  102. if (parent) {
  103. parent.appendChild(buttonDom);
  104. } else {
  105. console.log(`未找到父级容器,请查看父级容器类名是否为:${className}`)
  106. };
  107. };
  108.  
  109. // 搜索用户名称
  110. function searchUserCode(id) {
  111. if (!id) return;
  112. const userInfo = allCommoditiesArray.find(item => item.code == id);
  113. if (!userInfo) {
  114. window.alert('该ID对应的头像还没有生产出来喔~');
  115. return;
  116. };
  117. const name = userInfo.user ? userInfo.user.name : '该头像还没有主人,快去抢购吧~';
  118. window.alert(name);
  119. };
  120.  
  121. // ===========================================================================================
  122. // 签到接口请求参数
  123. const signinInterface = {
  124. "operationName": "signIn",
  125. "variables": {},
  126. "query": "mutation signIn {\n signIn\n}\n"
  127. };
  128.  
  129. isSignin(URL, signinInterface);
  130. // 自动签到
  131. async function isSignin(url, data) {
  132. // 首次加载立马调用一次,判断是否已签到
  133. const result = await request(url, data);
  134. console.log('签到信息', result);
  135. // 开启定时器,等到明天早上10点后执行签到(页面不关闭的情况,页面关闭需要重新打开播鸭页面)
  136. let date = new Date();
  137. date = date.setDate(date.getDate() + 1);
  138. date = new Date(date);
  139.  
  140. const y = date.getFullYear(),
  141. m = date.getMonth() + 1, // 月
  142. d = date.getDate(), // 日
  143. diffTime = new Date(`${y}-${m}-${d} 10:00:00`).getTime() - Date.now();
  144. setTimeout(() => {
  145. isSignin(url, data);
  146. }, diffTime);
  147. }
  148.  
  149. // ===========================================================================================
  150. // 封装请求接口
  151. async function request(url, data, type = 'POST') {
  152. const parse = {
  153. method: type,
  154. headers: {
  155. 'Content-Type': 'application/json',
  156. 'Authorization': `Bearer ${Token}`
  157. }
  158. };
  159. if (type === 'POST') {
  160. parse.body = JSON.stringify(data);
  161. }
  162. return fetch(url, parse).then(res => res.json());
  163. }
  164. })();

QingJ © 2025

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