乐子人玩家指示器

B站视频及动态评论区自动标注各种游戏玩家,依据是动态里是否有各种游戏相关,可自定义关键词,提供给各位乐子人,纯图一乐,默认添加了原神、幻塔、明日方舟等高热度游戏(乐子人角度)

  1. // ==UserScript==
  2. // @name 乐子人玩家指示器
  3. // @version 0.9
  4. // @description B站视频及动态评论区自动标注各种游戏玩家,依据是动态里是否有各种游戏相关,可自定义关键词,提供给各位乐子人,纯图一乐,默认添加了原神、幻塔、明日方舟等高热度游戏(乐子人角度)
  5. // @author xulaupuz,trychen,abcd1234564499sc
  6. // @match https://*.bilibili.com/*
  7. // @icon https://static.hdslb.com/images/favicon.ico
  8. // @connect bilibili.com
  9. // @grant GM_xmlhttpRequest
  10. // @license GPLv3
  11. // @run-at document-end
  12. // @namespace https://gf.qytechs.cn/users/958001
  13. // ==/UserScript==
  14.  
  15.  
  16. (function() {
  17. 'use strict';
  18. const solvedPid = new Set()
  19. const solvedDict = {}
  20. const checkArr = []
  21. // 添加各种关键词、关注B站号的UID,以及对应标签
  22. checkArr.push({
  23. "tag":"原神玩家",
  24. "keywords":["原神"],
  25. "followings": [401742377] // 官方号的 UID
  26. })
  27. checkArr.push({
  28. "tag":"幻塔玩家",
  29. "keywords":["幻塔"],
  30. "followings": [586631367] // 官方号的 UID
  31. })
  32. checkArr.push({
  33. "tag":"明日方舟玩家",
  34. "keywords":["明日方舟"],
  35. "followings": [161775300] // 官方号的 UID
  36. })
  37. checkArr.push({
  38. "tag":"碧蓝航线玩家",
  39. "keywords":["碧蓝航线"],
  40. "followings": [233114659] // 官方号的 UID
  41. })
  42. checkArr.push({
  43. "tag":"崩坏三玩家",
  44. "keywords":["崩坏三","崩坏3"],
  45. "followings": [27534330] // 官方号的 UID
  46. })
  47. checkArr.push({
  48. "tag":"FGO玩家",
  49. "keywords":["fgo","fate grand order"],
  50. "followings": [233108841] // 官方号的 UID
  51. })
  52.  
  53. const blog = 'https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space?&host_mid='
  54. const is_new = document.getElementsByClassName('item goback').length != 0 // 检测是不是新版
  55.  
  56. const get_pid = (c) => {
  57. if (is_new) {
  58. return c.dataset['userId']
  59. } else {
  60. return c.children[0]['href'].replace(/[^\d]/g, "")
  61. }
  62. }
  63.  
  64. const get_comment_list = () => {
  65. let lst = new Set()
  66. for (let c of document.getElementsByClassName('user-name')) {
  67. lst.add(c)
  68. }
  69. for (let c of document.getElementsByClassName('sub-user-name')) {
  70. lst.add(c)
  71. }
  72. for (let c of document.getElementsByClassName('user')) {
  73. lst.add(c)
  74. }
  75. return lst
  76. }
  77.  
  78. const get_tag = (context,checkArr) => {
  79. context = context.toLowerCase()
  80. let reTags = new Set()
  81. checkArr.forEach(checkDict => {
  82. // 检查动态内容
  83. if (checkDict.keywords){
  84. if (checkDict.keywords.find(keyword => context.includes(keyword))) {
  85. reTags.add(checkDict.tag)
  86. return
  87. }
  88. }
  89.  
  90. // 检查关注列表
  91. if (checkDict.followings){
  92. if (checkDict.followings.find(keyword => context.includes(keyword))) {
  93. reTags.add(checkDict.tag)
  94. return
  95. }
  96. }
  97. })
  98. return reTags
  99. }
  100.  
  101. const create_tags = (elem,tags) =>{
  102. // 动态使用的样式
  103. let divModelStart = '<div class="true-love" style="width: '
  104. let divModelMiddle = 'px; padding-left: 2px; padding-right: 0; border-color:rgba(169, 195, 233, 0.1803921568627451); color:rgba(87, 127, 184, 1); background-image: linear-gradient(90deg, rgba(244, 109, 67, 0.2), rgba(244, 109, 67, 0.2))"><div class="tinyfont">'
  105. let divModelEnd = '</div></div><div class="medal-level" style="border-color:rgba(169, 195, 233, 0.1803921568627451);color:rgba(154, 176, 210, 1) background-image: linear-gradient(90deg, rgba(158, 186, 232, 0.2), rgba(158, 186, 232, 0.2))"><div class="tinyfont">乐</div></div>'
  106.  
  107. // 视频评论区使用的样式
  108. let divModelStart2 = '<div class="composition-badge"><span class="composition-name">'
  109. let divModelEnd2 = '</span></div>'
  110.  
  111. tags.forEach(tag =>{
  112. var strLength = tag.length
  113. var modelLength = 12*strLength
  114. let divStr
  115. // 根据父节点判断当前元素类型
  116. var parentNode = elem.parentNode
  117. var parentNodeCls = parentNode.className
  118. let checkContent
  119. let addNode
  120. let newNode = document.createElement("div")
  121. if(parentNodeCls=="user-info"){
  122. //视频评论区主评论
  123. divStr = divModelStart2 + tag + divModelEnd2
  124. checkContent = parentNode.textContent
  125. addNode = parentNode
  126. newNode.setAttribute("class","composition-checkable")
  127. newNode.style="display: inline;"
  128. newNode.innerHTML = divStr
  129. } else if(parentNodeCls=="sub-user-info"){
  130. // 视频评论区评论回复
  131. divStr = divModelStart2 + tag + divModelEnd2
  132. checkContent = parentNode.textContent
  133. addNode = parentNode
  134. newNode.setAttribute("class","composition-checkable")
  135. newNode.style="display: inline;"
  136. newNode.innerHTML = divStr
  137. } else if(parentNodeCls=="con ") {
  138. // 动态评论区主评论
  139. divStr = divModelStart2 + tag + divModelEnd2
  140. checkContent = parentNode.textContent
  141. let tmpNodeMain = document.createElement("span")
  142. tmpNodeMain.style="marging:5px;float:right;"
  143. var beforeNodeMain = elem.nextSibling
  144. parentNode.insertBefore(tmpNodeMain,beforeNodeMain)
  145. addNode = tmpNodeMain
  146. newNode.setAttribute("class","medal")
  147. newNode.style="padding-left:0px"
  148. newNode.innerHTML = divStr
  149. } else if(parentNodeCls=="reply-con") {
  150. // 动态评论区评论回复
  151. divStr = divModelStart + modelLength + divModelMiddle + tag + divModelEnd
  152. checkContent = elem.textContent
  153. let tmpNode = document.createElement("span")
  154. var beforeNode = elem.getElementsByTagName("span")[0]
  155. elem.insertBefore(tmpNode,beforeNode)
  156. addNode = tmpNode
  157. newNode.setAttribute("class","medal")
  158. newNode.style="padding-left:0px"
  159. newNode.innerHTML = divStr
  160. } else {
  161. // 其他
  162. console.log(parentNodeCls)
  163. console.log(elem.textContent)
  164. }
  165. if (checkContent.includes(tag) === false) {
  166. addNode.appendChild(newNode)
  167. }
  168. })
  169. }
  170.  
  171. console.log(is_new)
  172.  
  173. console.log("正常加载")
  174. let jiance = setInterval(()=>{
  175. let commentlist = get_comment_list()
  176. if (commentlist.length != 0){
  177. // clearInterval(jiance)
  178. commentlist.forEach(c => {
  179. let pid = get_pid(c)
  180. if (solvedPid.has(pid)){
  181. var nowTags = solvedDict[pid]
  182. create_tags(c,nowTags)
  183. return
  184. }
  185.  
  186. //console.log(pid)
  187. let blogurl = blog + pid
  188. // let xhr = new XMLHttpRequest()
  189. GM_xmlhttpRequest({
  190. method: "get",
  191. url: blogurl,
  192. data: '',
  193. headers: {
  194. 'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
  195. },
  196. onload: function(res){
  197. if(res.status === 200){
  198. //console.log('成功')
  199. let st = JSON.stringify(JSON.parse(res.response).data)
  200. let reTags = get_tag(st,checkArr)
  201. //console.log(reTags)
  202. create_tags(c,reTags)
  203. solvedPid.add(pid)
  204. solvedDict[pid]=reTags
  205. }else{
  206. console.log('失败')
  207. console.log(res)
  208. }
  209. },
  210. });
  211. });
  212. }
  213. }, 4000)
  214. // 添加标签样式
  215. addGlobalStyle(`
  216. .composition-badge {
  217. display: inline-flex;
  218. justify-content: center;
  219. align-items: center;
  220. width: fit-content;
  221. background: #00AEEC26;
  222. border-radius: 10px;
  223. margin: -6px 0;
  224. margin: 0 5px;
  225. font-family: PingFang SC, HarmonyOS_Regular, Helvetica Neue, Microsoft YaHei, sans-serif;
  226. }
  227. .composition-name {
  228. line-height: 13px;
  229. font-size: 13px;
  230. color: #00AEEC;
  231. padding: 2px 8px;
  232. }
  233. .composition-icon {
  234. width: 25px;
  235. height: 25px;
  236. border-radius: 50%;
  237. border: 2px solid white;
  238. margin: -6px;
  239. margin-right: 5px;
  240. }
  241. `)
  242.  
  243. function addGlobalStyle(css) {
  244. var head, style;
  245. head = document.getElementsByTagName('head')[0];
  246. if (!head) { return; }
  247. style = document.createElement('style');
  248. style.type = 'text/css';
  249. style.innerHTML = css;
  250. head.appendChild(style);
  251. }
  252. })();

QingJ © 2025

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