bilibili勋章常亮

保持bilibili直播粉丝勋章常亮

  1. // ==UserScript==
  2. // @name bilibili勋章常亮
  3. // @namespace bilibili-medal
  4. // @version 0.7
  5. // @description 保持bilibili直播粉丝勋章常亮
  6. // @author HCLonely
  7. // @include https://link.bilibili.com/p/center/index
  8. // @run-at document-end
  9. // @require https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js
  10. // @require https://cdn.jsdelivr.net/npm/js-cookie@2.2.1/src/js.cookie.min.js
  11. // @require https://cdn.jsdelivr.net/npm/sweetalert2@11.0.19/dist/sweetalert2.all.min.js
  12. // @homepage https://blog.hclonely.com/posts/578f9be7/
  13. // @supportURL https://blog.hclonely.com/posts/578f9be7/
  14. // @connect api.live.bilibili.com
  15. // @grant GM_xmlhttpRequest
  16. // @grant GM_getValue
  17. // @grant GM_setValue
  18. // @grant GM_registerMenuCommand
  19. // ==/UserScript==
  20.  
  21. /* global $, Cookies, FormData */
  22. (function () {
  23. 'use strict'
  24. const blackList = GM_getValue('blackList') || []
  25. const whiteList = GM_getValue('whiteList') || []
  26. if (window.location.href === 'https://link.bilibili.com/p/center/index#/user-center/wearing-center/my-medal') {
  27. const find = setInterval(async () => {
  28. if ($('.page-title').length > 0) {
  29. clearInterval(find)
  30. const signBtn = $('<div class="link-panigation" style="display: inline;"><button data-v-461ef7c9="" class="panigation ts-dot-4" style="height: 30px;">开始签到</button></div>')
  31. signBtn.click(async () => {
  32. $('.text-ctnr').remove()
  33. $('table.center-grid>thead>tr').html('<td data-v-3895bb76="" width="160" style="padding-left: 60px;">主播昵称</td><td data-v-3895bb76="" width="160">直播间</td><td data-v-3895bb76="" width="120">签到结果</td>')
  34. $('table.center-grid>tbody').html('').after('<tfoot><tr><td colspan="3"><font id="delay-time">0</font> 秒后进行下一个房间签到</td></tr></tfoot>')
  35. const allRooms = whiteList.length > 0 ? whiteList : await getroomsId()
  36. for (let i = 0; i < allRooms.length; i++) {
  37. if (allRooms[i][1] < 100000) {
  38. allRooms[i][1] = await toLongId(allRooms[i][1])
  39. }
  40. }
  41. const rooms = allRooms.filter(e => !blackList.includes(e[1]))
  42. let i = 0
  43. $('nav.tabnav').append(`<section class="tabnav-item"><div class="tabnav-content">签到进度:${rooms.length} / <span id="sign-progress" class="tabnav-tip plain">${i}</span></div></section>`)
  44. for (const room of rooms) {
  45. await sendBiliMsg(room)
  46. i += 1;
  47. $('#sign-progress').text(i)
  48. const time = parseInt(Math.random() * (10000 - 6000 + 1) + 6000, 10)
  49. $('#delay-time').text(time / 1000)
  50. await delay(time)
  51. }
  52.  
  53. $('table.center-grid>tfoot').remove()
  54. // $('#sign-progress').text(++i)
  55. })
  56. $('.page-title').append(signBtn)
  57. }
  58. }, 1000)
  59. }
  60. const msgText = ['(⌒▽⌒)', '( ̄▽ ̄)', '(=・ω・=)', '(`・ω・´)', '(〜 ̄△ ̄)〜', '(・∀・)', '(°∀°)ノ', '( ̄3 ̄)', '╮( ̄▽ ̄)╭', '_(:3」∠)_', '( ´_ゝ`)', '←_←', '→_→', '(<_<)', '(>_>)', '(;¬_¬)', '("▔□▔)/', '(゚Д゚≡゚д゚)!?', 'Σ(゚д゚;)', 'Σ(  ̄□ ̄||)', '(´;ω;`)', '(/TДT)/', '(^・ω・^ )', '(。・ω・。)', '(● ̄(エ) ̄●)', 'ε=ε=(ノ≧∇≦)ノ', '(´・_・`)', '(-_-#)', '( ̄へ ̄)', '( ̄ε(# ̄) Σ', 'ヽ(`Д´)ノ', '(╯°口°)╯(┴—┴', '←◡←', '( ♥д♥)', 'Σ>―(〃°ω°〃)♡→', '⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄', '・*・:≡( ε:)']
  61. function sendBiliMsg([name, roomid]) {
  62. const csrf = Cookies.get('bili_jct')
  63. const formData = new FormData()
  64. formData.append('bubble', 0)
  65. formData.append('msg', msgText[Math.floor((Math.random() * msgText.length))])
  66. formData.append('color', 65532)
  67. formData.append('mode', 1)
  68. formData.append('fontsize', 25)
  69. formData.append('rnd', Math.floor(new Date().getTime() / 1000))
  70. formData.append('roomid', roomid)
  71. formData.append('csrf', csrf)
  72. formData.append('csrf_token', csrf)
  73. return new Promise(resolve => {
  74. GM_xmlhttpRequest({
  75. url: 'https://api.live.bilibili.com/msg/send',
  76. method: 'post',
  77. responseType: 'json',
  78. headers: {
  79. origin: 'https://live.bilibili.com',
  80. referer: 'https://live.bilibili.com/'
  81. },
  82. data: formData,
  83. onload: data => {
  84. if (data.response.code === 0) {
  85. $('table.center-grid>tbody').append(`<tr data-v-3895bb76=""><td data-v-3895bb76="" style="padding-left: 60px;">${name}</td><td data-v-3895bb76=""><a data-v-3895bb76="" target="blank" href="https://live.bilibili.com/${roomid}" class="bili-link cyan dp-i-block t-over-hidden t-no-wrap v-middle" style="max-width: 160px;">${roomid}</a></td><td data-v-3895bb76=""><span data-v-3895bb76="" class="dp-i-block t-over-hidden t-no-wrap" style="color:green;">成功</span></td></tr>`)
  86. } else {
  87. console.log(data)
  88. $('table.center-grid>tbody').append(`<tr data-v-3895bb76=""><td data-v-3895bb76="" style="padding-left: 60px;">${name}</td><td data-v-3895bb76=""><a data-v-3895bb76="" target="blank" href="https://live.bilibili.com/${roomid}" class="bili-link cyan dp-i-block t-over-hidden t-no-wrap v-middle" style="max-width: 160px;">${roomid}</a></td><td data-v-3895bb76=""><span data-v-3895bb76="" class="dp-i-block t-over-hidden t-no-wrap" style="color:red;">失败:${data.response.message + '|' + data.response.msg}</span></td></tr>`)
  89. }
  90. resolve()
  91. },
  92. onerror: (data) => {
  93. console.log(data)
  94. $('table.center-grid>tbody').append(`<tr data-v-3895bb76=""><td data-v-3895bb76="" style="padding-left: 60px;">${name}</td><td data-v-3895bb76=""><a data-v-3895bb76="" target="blank" href="https://live.bilibili.com/${roomid}" class="bili-link cyan dp-i-block t-over-hidden t-no-wrap v-middle" style="max-width: 160px;">${roomid}</a></td><td data-v-3895bb76=""><span data-v-3895bb76="" class="dp-i-block t-over-hidden t-no-wrap" style="color:red;">失败</span></td></tr>`)
  95. resolve()
  96. }
  97. })
  98. })
  99. }
  100. function getroomsId(i=1) {
  101. return new Promise(resolve => {
  102. GM_xmlhttpRequest({
  103. url: `https://api.live.bilibili.com/xlive/app-ucenter/v1/fansMedal/panel?page=${i}&page_size=50&target_id=${$('#right-part a[href*="space.bilibili.com"]').attr('href').match(/[\d]+/)?.[0]}`,
  104. method: 'get',
  105. responseType: 'json',
  106. headers: {
  107. 'origin': 'https://link.bilibili.com',
  108. 'referer': 'https://link.bilibili.com/p/center/index'
  109. },
  110. onload: async data => {
  111. if (data.response.code === 0) {
  112. if (i * 50 < data.response.data.total_number) {
  113. const prevPageData = await getroomsId(i + 1);
  114. resolve([...prevPageData, [...data.response.data.list, ...data.response.data.special_list].filter(e => e.room_info?.room_id && e.medal.today_feed < 100 && !blackList.includes(e.room_info?.roomid)).map(e => [e.anchor_info?.nick_name, e.room_info?.room_id]).filter(e => e[1])])
  115. } else {
  116. resolve([...data.response.data.list, ...data.response.data.special_list].filter(e => e.room_info?.room_id && e.medal.today_feed < 100 && !blackList.includes(e.room_info?.roomid)).map(e => [e.anchor_info?.nick_name, e.room_info?.room_id]).filter(e => e[1]))
  117. }
  118. } else {
  119. resolve(false)
  120. }
  121. },
  122. onerror: () => {
  123. resolve(false)
  124. }
  125. })
  126. })
  127. }
  128. function delay(time) {
  129. return new Promise(resolve => {
  130. setTimeout(() => {
  131. resolve()
  132. }, time)
  133. })
  134. }
  135. async function toLongId(id) {
  136. const cache = GM_getValue('ids') || {}
  137. if (cache[id]) {
  138. return cache[id]
  139. }
  140. return await new Promise(resolve => {
  141. GM_xmlhttpRequest({
  142. url: 'http://api.live.bilibili.com/room/v1/Room/room_init?id=' + id,
  143. method: 'get',
  144. responseType: 'json',
  145. onload: data => {
  146. if (data.response.code === 0) {
  147. const longId = data.response.data.room_id
  148. cache[id] = longId
  149. GM_setValue('ids', cache)
  150. resolve(longId)
  151. } else {
  152. resolve(id)
  153. }
  154. },
  155. onerror: () => {
  156. resolve(id)
  157. }
  158. })
  159. })
  160. }
  161. GM_registerMenuCommand('设置黑名单', () => {
  162. const blackList = GM_getValue('blackList') || []
  163. Swal.fire({
  164. title: '设置黑名单',
  165. input: 'textarea',
  166. inputValue: blackList.join(','),
  167. showCancelButton: true,
  168. confirmButtonText: '保存',
  169. cancelButtonText: '取消'
  170. }).then(({ value }) => {
  171. if (value) {
  172. GM_setValue('blackList', value.split(',').map(e => parseInt(e)))
  173. Swal.fire(
  174. '保存成功',
  175. '',
  176. 'success'
  177. )
  178. }
  179. })
  180. })
  181. GM_registerMenuCommand('设置白名单', () => {
  182. const whiteList = GM_getValue('whiteList') || []
  183. Swal.fire({
  184. title: '设置白名单',
  185. input: 'textarea',
  186. inputValue: whiteList.join(','),
  187. showCancelButton: true,
  188. confirmButtonText: '保存',
  189. cancelButtonText: '取消'
  190. }).then(({ value }) => {
  191. if (value) {
  192. GM_setValue('whiteList', value.split(',').map(e => parseInt(e)))
  193. Swal.fire(
  194. '保存成功',
  195. '',
  196. 'success'
  197. )
  198. }
  199. })
  200. })
  201. })()

QingJ © 2025

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