b站vtuber直播同传评论转字幕

将vtuber直播时同传man的评论,以类似底部弹幕的形式展现在播放器窗口,免去在众多快速刷过的评论中找同传man的痛苦。

  1. // ==UserScript==
  2. // @name b站vtuber直播同传评论转字幕
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.3.5
  5. // @author Manakanemu
  6. // @include https://live.bilibili.com/*
  7. // @exclude https://live.bilibili.com/p/*
  8. // @grant GM_xmlhttpRequest
  9. // @require https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js
  10. // @require https://cdn.staticfile.org/vue/2.6.11/vue.min.js
  11. // @connect youdao.com
  12. // @description 将vtuber直播时同传man的评论,以类似底部弹幕的形式展现在播放器窗口,免去在众多快速刷过的评论中找同传man的痛苦。
  13. // GM_xmlhttpRequest
  14.  
  15. // ==/UserScript==
  16.  
  17.  
  18. (function () {
  19. // 字幕样式配置
  20.  
  21. const youdaoAPI = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
  22.  
  23. const removeBracket = true
  24. // 所有组件挂在attentionModul下,以App结尾的为绑定DOm的vue组件
  25. window.attentionModul = {}
  26. window.attentionModul.commentApp = {} // 字幕组件
  27. window.attentionModul.consoleApp = {} // 控制面板组件
  28. window.attentionModul.transApp = {} // 翻译组件
  29. window.attentionModul.users = [] // 关注用户列表
  30. window.attentionModul.observe = {} // DOM突变时间监听器
  31. // 从localstorage读取配置
  32. window.attentionModul.config = JSON.parse(localStorage.getItem('config') || '{"color":"#ffffff","font-size":40}')
  33. window.attentionModul.md5 = md5
  34.  
  35. // 测试用组件
  36. window.attentionModul.debug = {}
  37. window.attentionModul.debug.setComment = setComment
  38. window.attentionModul.debug.addAttentionUser = addAttentionUser
  39. window.attentionModul.debug.showDOM = showDOM
  40. window.attentionModul.debug.addComment = addComment
  41. window.attentionModul.test = function () {
  42.  
  43. window.attentionModul.debug.setComment(0, '测试')
  44. window.attentionModul.debug.setComment(1, '测试测试')
  45. }
  46.  
  47. // 添加关注用户
  48. function addAttentionUser(uid) {
  49. $('textarea:eq(0)').click()
  50. if (window.attentionModul.users.indexOf(uid) < 0) {
  51. window.attentionModul.users.push(uid)
  52. window.attentionModul.commentApp.comments.push(null)
  53. }
  54. }
  55.  
  56. // 添加测试评论
  57. function addComment(uid = 'test', uname = '测试', comment = '测试评论') {
  58. const localComment = $('<div data-uid="' + uid + '" data-uname="' + uname + '" data-danmaku="' + comment + '">' + comment + '</div>')
  59. $('.chat-history-list ').append(localComment)
  60. }
  61.  
  62. // 移除关注用户
  63. function removeAttentionUser() {
  64.  
  65. }
  66.  
  67. // 调试显示组件
  68. function showDOM() {
  69. return [document.getElementById('comment-container'), document.getElementById('console-container')]
  70. }
  71.  
  72. // 移除括号
  73. function removeBreaket(comment) {
  74. let r = comment.match(/^[ 【]*(.*?)[ 】]*$/i)[1]
  75. return r
  76. }
  77.  
  78. //将匹配评论添加到vue变量中对应的字幕DOM
  79. function setComment(index, comment, username = '同传man') {
  80. window.attentionModul.commentApp.comments.splice(index, 1, comment)
  81. }
  82.  
  83. // 对象编码为url参数
  84.  
  85.  
  86. //匹配评论发出者与关注用户
  87. function chatFilter(nodeList) {
  88. for (let item of nodeList) {
  89. const uid = item.getAttribute('data-uid')
  90. const comment = item.getAttribute('data-danmaku')
  91. const username = item.getAttribute('data-uname')
  92. const index = window.attentionModul.users.indexOf(uid)
  93. if (index > -1) {
  94. if (removeBreaket) {
  95. setComment(index, removeBreaket(comment), username)
  96. } else {
  97. setComment(index, comment, username)
  98. }
  99. }
  100. }
  101. }
  102.  
  103. // DOM突变事件回调函数
  104. function mutationListener(mutationList) {
  105. window.attentionModul.observe.message = mutationList
  106.  
  107. if (window.attentionModul.observe.message[0].addedNodes.length > 0) {
  108. chatFilter(window.attentionModul.observe.message[0].addedNodes)
  109. }
  110. }
  111.  
  112. //保存控制台配置
  113. function saveConfig() {
  114. const config = {
  115. "color": window.attentionModul.consoleApp.color,
  116. // "vertical": window.attentionModul.consoleApp.vertical,
  117. // "font-size": window.attentionModul.consoleApp.fontSize
  118. }
  119. localStorage.setItem('config', JSON.stringify(config))
  120. }
  121.  
  122. // 注入控制台组件
  123. ;(function () {
  124. const consoleContainer = $('<div @mouseleave="consoleOut" @mouseover.stop="consoleIn" id="console-container" class="att-top"></div>')
  125. const widgetIcon = $('<div v-show="!isShowConsole" class="att-icon-container att-top" ><div class="att-icon"></div></div>')
  126. const consoleWidget = $('<div v-show="isShowConsole" id="att-console" class="att-col"></div>')
  127. const verticalWidget = $('<div class="att-console-title" style="cursor:pointer;" @click="resetFontPosandSize">重置字幕位置/字号</div>')
  128. // const fontSizeWidget = $('<div class="att-console-title">恢复字幕默认设置</div><div class="att-row"><input @input="changeFontsize" class="att-input-range" type="range" v-model:value="fontSize" min="1" max="500" step="5"><input class="att-input-value" v-model:value="fontSize" @change="changeFontsize"></div>')
  129. const colorWidget = $('<div class="att-console-title">字幕颜色</div><div class="att-row"><input class="att-input-range" placeholder="示例:#030303" v-model:value="color" @change="changeColor" style="padding: 2px;border-radius: 2px;border: 0;border-bottom: 1px solid gray"><div @click="defualtColor" style="cursor:pointer;">默认</div></div>')
  130. consoleWidget.append(verticalWidget)
  131. // consoleWidget.append(fontSizeWidget)
  132. consoleWidget.append(colorWidget)
  133. consoleContainer.append(widgetIcon)
  134. consoleContainer.append(consoleWidget)
  135. $('body').append(consoleContainer)
  136.  
  137. const config = window.attentionModul.config
  138. window.attentionModul.consoleApp = new Vue({
  139. el: '#console-container',
  140. data() {
  141. return {
  142. isShowConsole: false,
  143. fontSize: config['font-size'] || 25,
  144. color: config['color'] || '#ffffff'
  145. }
  146. },
  147. methods: {
  148. consoleIn() {
  149. this.isShowConsole = true
  150. },
  151. consoleOut() {
  152. this.isShowConsole = false
  153. },
  154. changeFontsize(){
  155. $('#comment-container').css('font-size', this.fontSize.toString()+'px')
  156. },
  157. changeColor() {
  158. $('#comment-container').css('color', this.color.toString())
  159. saveConfig()
  160. },
  161. defualtColor() {
  162. this.color = '#ffffff'
  163. $('#comment-container').css('color', this.color.toString())
  164. saveConfig()
  165. },
  166. resetFontPosandSize(){
  167. window.attentionModul.commentApp.widgetStyle = ''
  168. $('#comment-container').css('font-size', '25px')
  169.  
  170. }
  171. }
  172. })
  173. })();
  174.  
  175. // 注入字幕组件
  176. ;(function insertCommentWidget() {
  177. const container = $('.bilibili-live-player-video-area')
  178. if (container.length > 0) {
  179. const commentWidget = $('<div id="comment-container" :style="widgetStyle" :class="{\'att-comment-fixed\':isFixed,\'att-comment-float\':!isFixed}"><div class="att-comment-box"><span v-show="htmlString" v-html="htmlString" class="att-comment-span" :style="commentStyle" @mousedown="mousedown" @wheel.stop.prevent="mousewheel" @mousemove="mousemove"></span></div></div>')
  180. container.append(commentWidget)
  181. window.attentionModul.commentApp = new Vue({
  182. el: '#comment-container',
  183. data() {
  184. return {
  185. widgetStyle: '',
  186. boxStyle: '',
  187. comments: new Array(window.attentionModul.users.length),
  188. commentStyle: '',
  189. dom: document.getElementById('comment-container'),
  190. htmlString: '',
  191. isFixed: true,
  192. spanLeft: 0,
  193. spanTop: 0,
  194. localLeft: 0,
  195. localTop: 0,
  196. isdrag: false,
  197. dragStartLeft: 0,
  198. dragStartTop: 0,
  199. dragEndLeft: 0,
  200. dragEndTop: 0,
  201. moveX: 0,
  202. moveY: 0
  203. }
  204. },
  205. watch: {
  206. comments(data) {
  207. let htmlString = ''
  208. const length = data.length
  209. for (let i = 0; i < length - 1; i++) {
  210. if (data[i]) {
  211. htmlString += data[i] + '<br>'
  212. }
  213. }
  214. if (data[length - 1]) {
  215. htmlString += data[length - 1]
  216. }
  217. this.htmlString = htmlString
  218. },
  219. immediate: true
  220. },
  221. methods: {
  222. mousedown() {
  223. this.isdrag = true
  224. const widget = $('#comment-container')
  225. const span = $('.att-comment-span')
  226. this.localLeft = widget.position().left
  227. this.localTop = widget.position().top
  228. if (this.isFixed) {
  229. this.isFixed = false
  230. }
  231. this.widgetStyle = 'transform:translate(' + this.localLeft.toString() + 'px,' + this.localTop.toString() + 'px)'
  232. this.spanLeft = span.offset().left
  233. this.spanTop = span.offset().top
  234. },
  235. mousemove(e) {
  236. },
  237. mousewheel(e){
  238. const widget = $('#comment-container')
  239. let fontSize = parseInt(widget.css('font-size'))
  240. if(e.wheelDeltaY){
  241. fontSize -= e.deltaY/25
  242. }else {
  243. fontSize -= e.deltaY
  244.  
  245. }
  246. widget.css('font-size',fontSize.toString() + 'px')
  247. }
  248. ,
  249. transform() {
  250. this.isFixed = true
  251. const widget = $('#comment-container')
  252. const player = $('.bilibili-live-player-video-area')
  253.  
  254. const widgetX = widget.position().left
  255. const widgetY = widget.position().top
  256. const widgetHeight = widget.outerHeight()
  257. const widgetWidth = widget.outerWidth()
  258.  
  259. const heightLevel = widgetY + widgetHeight / 2
  260. const widthLevel = widgetX + widgetWidth / 2
  261. const playerHeight = player.innerHeight()
  262. const playerWidth = player.innerWidth()
  263.  
  264. if (heightLevel > playerHeight / 2) {
  265. if (widthLevel > playerWidth / 2) {
  266. //右下
  267. this.widgetStyle = 'bottom:' + (playerHeight - widgetY - widgetHeight).toString() + 'px;right:' + (playerWidth - widgetX - widgetWidth).toString() + 'px'
  268. } else {
  269. // 左下
  270. this.widgetStyle = 'bottom:' + (playerHeight - widgetY - widgetHeight).toString() + 'px;left:' + (widgetX).toString() + 'px'
  271. }
  272. } else {
  273. if (widthLevel > playerWidth / 2) {
  274. // 右上
  275. this.widgetStyle = 'top:' + (widgetY).toString() + 'px;right:' + (playerWidth - widgetX - widgetWidth).toString() + 'px'
  276.  
  277. } else {
  278. // 左上
  279. this.widgetStyle = 'top:' + (widgetY).toString() + 'px;left:' + (widgetX).toString() + 'px'
  280.  
  281. }
  282. }
  283. }
  284. ,
  285. isInnerY(moveY) {
  286. const videoPlayer = $('.bilibili-live-player-video-area')
  287. const comment = $('.att-comment-span')
  288. const playerStartY = videoPlayer.offset().top + 1
  289. const playerEndY = playerStartY + videoPlayer.height() - 2
  290. const commentStartY = this.spanTop + moveY
  291. const commentEndY = commentStartY + comment.innerHeight()
  292. if (commentStartY <= playerStartY || commentEndY >= playerEndY) {
  293. return false
  294. } else {
  295. return true
  296. }
  297. },
  298. isInnerX(moveX) {
  299. const videoPlayer = $('.bilibili-live-player-video-area')
  300. const comment = $('.att-comment-span')
  301. const playerStartX = videoPlayer.offset().left + 1
  302. const playerEndX = playerStartX + videoPlayer.width() - 2
  303. const commentStartX = this.spanLeft + moveX
  304. const commentEndX = commentStartX + comment.innerWidth()
  305. if (commentStartX <= playerStartX || commentEndX >= playerEndX) {
  306. return false
  307. } else {
  308. return true
  309. }
  310. }
  311. }
  312. })
  313. // window.attentionModul.consoleApp.changeVertical()
  314. window.attentionModul.consoleApp.changeColor()
  315. window.attentionModul.consoleApp.changeFontsize()
  316.  
  317. $('body').bind('mousemove', function (e) {
  318. if (window.attentionModul.commentApp.isdrag) {
  319. const moveX = e.screenX - window.attentionModul.commentApp.dragStartLeft
  320. const moveY = e.screenY - window.attentionModul.commentApp.dragStartTop
  321. const isInnerX = window.attentionModul.commentApp.isInnerX(moveX)
  322. const isInnerY = window.attentionModul.commentApp.isInnerY(moveY)
  323. if (isInnerX) {
  324. window.attentionModul.commentApp.moveX = moveX
  325. }
  326. if (isInnerY) {
  327. window.attentionModul.commentApp.moveY = moveY
  328. }
  329. window.attentionModul.commentApp.widgetStyle = 'transform:translate(' + (window.attentionModul.commentApp.localLeft + window.attentionModul.commentApp.moveX).toString() + 'px,' + (window.attentionModul.commentApp.localTop + window.attentionModul.commentApp.moveY).toString() + 'px)'
  330.  
  331. } else {
  332. window.attentionModul.commentApp.dragStartLeft = e.screenX
  333. window.attentionModul.commentApp.dragStartTop = e.screenY
  334. }
  335. })
  336. $('body').bind('mouseup', function () {
  337. if (window.attentionModul.commentApp.isdrag) {
  338. window.attentionModul.commentApp.isdrag = false
  339. window.attentionModul.commentApp.transform()
  340. }
  341. })
  342. } else {
  343. requestAnimationFrame(function () {
  344. insertCommentWidget()
  345. })
  346. }
  347. })();
  348.  
  349. // 注入菜单组件
  350. ;(function insertMenuWidget() {
  351. const menu = $('.danmaku-menu')
  352. const menuItem = menu.find('.report-this-guy')
  353. if (menuItem.length > 0) {
  354. let a = $('<a href="javascript:;" class="bili-link pointer" style="display: block">添加字幕特别关注</a>')
  355. menuItem.append(a)
  356. // 添加点击函数,获取用户uid,调用add函数添加到关注用户列表
  357. a.click(function () {
  358. const uid = menu[0].__vue__.uid
  359. const username = menu[0].__vue__.username
  360. addAttentionUser(uid.toString())
  361. })
  362. } else {
  363. requestAnimationFrame(function () {
  364. insertMenuWidget()
  365. })
  366. }
  367. }
  368. )();
  369.  
  370. // 注入翻译组件
  371. ;(function insertTranslateWidget() {
  372. let injectAnchor = $('.right-action')
  373. if (injectAnchor.length > 0) {
  374. const translateButton = $('<button id="att-translate" class="att-button" @click="translate" style="cursor: pointer;">翻译</button>')
  375. injectAnchor.prepend(translateButton)
  376. window.attentionModul.transApp = new Vue({
  377. el: '#att-translate',
  378. data() {
  379. return {commentVm: document.getElementsByClassName('control-panel-ctnr')[0].__vue__}
  380. },
  381. methods: {
  382. translate() {
  383. function encodeObject(obj) {
  384. let param = ''
  385. for (let key in obj) {
  386. param += key + '=' + encodeURIComponent(obj[key]) + '&'
  387. }
  388. return param.substring(0, param.length - 1)
  389. }
  390.  
  391. function getParam(query) {
  392. const bv = md5(navigator.appVersion)
  393. const ts = "" + (new Date).getTime()
  394. const salt = ts + parseInt(10 * Math.random(), 10);
  395. const sign = md5("fanyideskweb" + query + salt + "Nw(nmmbP%A-r6U3EUn]Aj")
  396. return {
  397. i: query,
  398. from: "AUTO",
  399. to: 'ja',
  400. smartresult: 'dict',
  401. client: 'fanyideskweb',
  402. salt: salt,
  403. sign: sign,
  404. ts: ts,
  405. // bv: bv,
  406. doctype: "json",
  407. version: "2.1",
  408. keyfrom: "fanyi.web",
  409. action: "FY_BY_CLICKBUTTION"
  410. }
  411. }
  412.  
  413. const query = this.commentVm.chatInput
  414. const url = youdaoAPI
  415. const param = getParam(query)
  416. GM_xmlhttpRequest({
  417. method: 'POST',
  418. url: url,
  419. headers: {
  420. "Content-Type": "application/x-www-form-urlencoded",
  421. "Referer": "http://fanyi.youdao.com/"
  422. },
  423. data: encodeObject(param),
  424. onload: function (r) {
  425. const res = JSON.parse(r.responseText)
  426. if (res.translateResult) {
  427. window.attentionModul.transApp.commentVm.chatInput = res.translateResult[0][0].tgt
  428. }
  429. }
  430. })
  431. }
  432. }
  433. })
  434. } else {
  435. requestAnimationFrame((function () {
  436. insertTranslateWidget()
  437. }))
  438. }
  439. })();
  440.  
  441. // 监听评论DOM突变事件
  442. window.attentionModul.observe.observer = new MutationObserver(mutationListener)
  443.  
  444. window.attentionModul.observe.config = {childList: true,subtree: true}
  445. ;(function openObserver() {
  446. window.attentionModul.observe.anchor = document.getElementsByClassName('chat-history-list')[0]
  447. if (window.attentionModul.observe.anchor) {
  448. cancelAnimationFrame(window.attentionModul.index)
  449. window.attentionModul.observe.observer.observe(window.attentionModul.observe.anchor, window.attentionModul.observe.config)
  450. } else {
  451. window.attentionModul.index = requestAnimationFrame(function () {
  452. openObserver()
  453. }
  454. )
  455. }
  456. })();
  457.  
  458.  
  459. function md5(md5str) {
  460. var createMD5String = function (string) {
  461. var x = Array()
  462. var k, AA, BB, CC, DD, a, b, c, d
  463. var S11 = 7,
  464. S12 = 12,
  465. S13 = 17,
  466. S14 = 22
  467. var S21 = 5,
  468. S22 = 9,
  469. S23 = 14,
  470. S24 = 20
  471. var S31 = 4,
  472. S32 = 11,
  473. S33 = 16,
  474. S34 = 23
  475. var S41 = 6,
  476. S42 = 10,
  477. S43 = 15,
  478. S44 = 21
  479. string = uTF8Encode(string)
  480. x = convertToWordArray(string)
  481. a = 0x67452301
  482. b = 0xEFCDAB89
  483. c = 0x98BADCFE
  484. d = 0x10325476
  485. for (k = 0; k < x.length; k += 16) {
  486. AA = a
  487. BB = b
  488. CC = c
  489. DD = d
  490. a = FF(a, b, c, d, x[k + 0], S11, 0xD76AA478)
  491. d = FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756)
  492. c = FF(c, d, a, b, x[k + 2], S13, 0x242070DB)
  493. b = FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE)
  494. a = FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF)
  495. d = FF(d, a, b, c, x[k + 5], S12, 0x4787C62A)
  496. c = FF(c, d, a, b, x[k + 6], S13, 0xA8304613)
  497. b = FF(b, c, d, a, x[k + 7], S14, 0xFD469501)
  498. a = FF(a, b, c, d, x[k + 8], S11, 0x698098D8)
  499. d = FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF)
  500. c = FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1)
  501. b = FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE)
  502. a = FF(a, b, c, d, x[k + 12], S11, 0x6B901122)
  503. d = FF(d, a, b, c, x[k + 13], S12, 0xFD987193)
  504. c = FF(c, d, a, b, x[k + 14], S13, 0xA679438E)
  505. b = FF(b, c, d, a, x[k + 15], S14, 0x49B40821)
  506. a = GG(a, b, c, d, x[k + 1], S21, 0xF61E2562)
  507. d = GG(d, a, b, c, x[k + 6], S22, 0xC040B340)
  508. c = GG(c, d, a, b, x[k + 11], S23, 0x265E5A51)
  509. b = GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA)
  510. a = GG(a, b, c, d, x[k + 5], S21, 0xD62F105D)
  511. d = GG(d, a, b, c, x[k + 10], S22, 0x2441453)
  512. c = GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681)
  513. b = GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8)
  514. a = GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6)
  515. d = GG(d, a, b, c, x[k + 14], S22, 0xC33707D6)
  516. c = GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87)
  517. b = GG(b, c, d, a, x[k + 8], S24, 0x455A14ED)
  518. a = GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905)
  519. d = GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8)
  520. c = GG(c, d, a, b, x[k + 7], S23, 0x676F02D9)
  521. b = GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A)
  522. a = HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942)
  523. d = HH(d, a, b, c, x[k + 8], S32, 0x8771F681)
  524. c = HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122)
  525. b = HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C)
  526. a = HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44)
  527. d = HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9)
  528. c = HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60)
  529. b = HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70)
  530. a = HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6)
  531. d = HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA)
  532. c = HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085)
  533. b = HH(b, c, d, a, x[k + 6], S34, 0x4881D05)
  534. a = HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039)
  535. d = HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5)
  536. c = HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8)
  537. b = HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665)
  538. a = II(a, b, c, d, x[k + 0], S41, 0xF4292244)
  539. d = II(d, a, b, c, x[k + 7], S42, 0x432AFF97)
  540. c = II(c, d, a, b, x[k + 14], S43, 0xAB9423A7)
  541. b = II(b, c, d, a, x[k + 5], S44, 0xFC93A039)
  542. a = II(a, b, c, d, x[k + 12], S41, 0x655B59C3)
  543. d = II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92)
  544. c = II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D)
  545. b = II(b, c, d, a, x[k + 1], S44, 0x85845DD1)
  546. a = II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F)
  547. d = II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0)
  548. c = II(c, d, a, b, x[k + 6], S43, 0xA3014314)
  549. b = II(b, c, d, a, x[k + 13], S44, 0x4E0811A1)
  550. a = II(a, b, c, d, x[k + 4], S41, 0xF7537E82)
  551. d = II(d, a, b, c, x[k + 11], S42, 0xBD3AF235)
  552. c = II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB)
  553. b = II(b, c, d, a, x[k + 9], S44, 0xEB86D391)
  554. a = addUnsigned(a, AA)
  555. b = addUnsigned(b, BB)
  556. c = addUnsigned(c, CC)
  557. d = addUnsigned(d, DD)
  558. }
  559. var tempValue = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d)
  560. return tempValue.toLowerCase()
  561. }
  562. var rotateLeft = function (lValue, iShiftBits) {
  563. return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits))
  564. }
  565. var addUnsigned = function (lX, lY) {
  566. var lX4, lY4, lX8, lY8, lResult
  567. lX8 = (lX & 0x80000000)
  568. lY8 = (lY & 0x80000000)
  569. lX4 = (lX & 0x40000000)
  570. lY4 = (lY & 0x40000000)
  571. lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF)
  572. if (lX4 & lY4) return (lResult ^ 0x80000000 ^ lX8 ^ lY8)
  573. if (lX4 | lY4) {
  574. if (lResult & 0x40000000) return (lResult ^ 0xC0000000 ^ lX8 ^ lY8)
  575. else return (lResult ^ 0x40000000 ^ lX8 ^ lY8)
  576. } else {
  577. return (lResult ^ lX8 ^ lY8)
  578. }
  579. }
  580. var F = function (x, y, z) {
  581. return (x & y) | ((~x) & z)
  582. }
  583. var G = function (x, y, z) {
  584. return (x & z) | (y & (~z))
  585. }
  586. var H = function (x, y, z) {
  587. return (x ^ y ^ z)
  588. }
  589. var I = function (x, y, z) {
  590. return (y ^ (x | (~z)))
  591. }
  592. var FF = function (a, b, c, d, x, s, ac) {
  593. a = addUnsigned(a, addUnsigned(addUnsigned(F(b, c, d), x), ac))
  594. return addUnsigned(rotateLeft(a, s), b)
  595. }
  596. var GG = function (a, b, c, d, x, s, ac) {
  597. a = addUnsigned(a, addUnsigned(addUnsigned(G(b, c, d), x), ac))
  598. return addUnsigned(rotateLeft(a, s), b)
  599. }
  600. var HH = function (a, b, c, d, x, s, ac) {
  601. a = addUnsigned(a, addUnsigned(addUnsigned(H(b, c, d), x), ac))
  602. return addUnsigned(rotateLeft(a, s), b)
  603. }
  604. var II = function (a, b, c, d, x, s, ac) {
  605. a = addUnsigned(a, addUnsigned(addUnsigned(I(b, c, d), x), ac))
  606. return addUnsigned(rotateLeft(a, s), b)
  607. }
  608. var convertToWordArray = function (string) {
  609. var lWordCount
  610. var lMessageLength = string.length
  611. var lNumberOfWordsTempOne = lMessageLength + 8
  612. var lNumberOfWordsTempTwo = (lNumberOfWordsTempOne - (lNumberOfWordsTempOne % 64)) / 64
  613. var lNumberOfWords = (lNumberOfWordsTempTwo + 1) * 16
  614. var lWordArray = Array(lNumberOfWords - 1)
  615. var lBytePosition = 0
  616. var lByteCount = 0
  617. while (lByteCount < lMessageLength) {
  618. lWordCount = (lByteCount - (lByteCount % 4)) / 4
  619. lBytePosition = (lByteCount % 4) * 8
  620. lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition))
  621. lByteCount++
  622. }
  623. lWordCount = (lByteCount - (lByteCount % 4)) / 4
  624. lBytePosition = (lByteCount % 4) * 8
  625. lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition)
  626. lWordArray[lNumberOfWords - 2] = lMessageLength << 3
  627. lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29
  628. return lWordArray
  629. }
  630. var wordToHex = function (lValue) {
  631. var WordToHexValue = '',
  632. WordToHexValueTemp = '',
  633. lByte, lCount
  634. for (lCount = 0; lCount <= 3; lCount++) {
  635. lByte = (lValue >>> (lCount * 8)) & 255
  636. WordToHexValueTemp = '0' + lByte.toString(16)
  637. WordToHexValue = WordToHexValue + WordToHexValueTemp.substr(WordToHexValueTemp.length - 2, 2)
  638. }
  639. return WordToHexValue
  640. }
  641. var uTF8Encode = function (string) {
  642. string = string.toString().replace(/\x0d\x0a/g, '\x0a')
  643. var output = ''
  644. for (var n = 0; n < string.length; n++) {
  645. var c = string.charCodeAt(n)
  646. if (c < 128) {
  647. output += String.fromCharCode(c)
  648. } else if ((c > 127) && (c < 2048)) {
  649. output += String.fromCharCode((c >> 6) | 192)
  650. output += String.fromCharCode((c & 63) | 128)
  651. } else {
  652. output += String.fromCharCode((c >> 12) | 224)
  653. output += String.fromCharCode(((c >> 6) & 63) | 128)
  654. output += String.fromCharCode((c & 63) | 128)
  655. }
  656. }
  657. return output
  658. }
  659. return createMD5String(md5str)
  660. }
  661.  
  662. const consoleStyle = `
  663.  
  664.  
  665.  
  666. .att-col{
  667. display: flex;
  668. flex-flow: column nowrap;
  669. place-content: center start;
  670. }
  671. .att-row{
  672. display: flex;
  673. flex-flow: row nowrap;
  674. place-content: center start;
  675. margin:3px 0px 3px 0px;
  676. }
  677. .att-top{
  678. z-index: 999;
  679. }
  680. .att-input{
  681. outline: none;
  682. }
  683. #console-container{
  684. position: absolute;
  685. left: 50px;
  686. top: 300px;
  687. min-height: 48px;
  688. min-width: 48px;
  689. }
  690. .att-icon-container {
  691. position: absolute;
  692. left: 0px;
  693. top: 0px;
  694. height: 48px;
  695. width: 48px;
  696. background-color: #fb7299;
  697. border-radius: 4px;
  698. }
  699. .att-icon {
  700. position: absolute;
  701. left: 50%;
  702. top: 50%;
  703. transform: translate(-50%, -50%);
  704. height: 32px;
  705. width: 32px;
  706. background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADFElEQVRYhe2XX2iPURjHP7+N0oYRWWObMZSUJjQKG/JnlCh/LkSaUG6URLlf8pNSciEX1AqzaEXKhdTMnVHmRogxtOZfG/m/r956Th3v791r7++nXPCt0znv8zznOd/3Oc95zvvyzyPlAiDpd7GYAywAioEioBd4BbQCd5MGMpVK/SoICAzQdku6p3i0S6qP8ZHRMhBhNN8c++iSdFVSk/UvQvo2SbP+BIGNIceNkhZKKgjZFUqqkXTOs/0maXUuBJZ4zh5KWjzIsC6T9NSbm5Y0NymBIknvzcEDSWOT7KukkhCJAGclTRwsgVM26Yuk8oSLu1Yp6WuIRI9tVSyBUm/CviwXd+2g+en3fP6QVB1HYK8ZvpGUnyOBYZJ6jUCDpFvmu9slskOex2GB9ZeAH5kUE+Ez0GKF7iOwxmTjgHSkI0mPjOX20NuMkTQlJJsRse/hhN1t/jrseZe3HSVRBD6ass5zEpyKZ5I+SJpnsrQl2RF7DuR9kp6bvZu71vy982TdLseitsCN/QwZBpQBhcAok00DhgJT7Xk0MBwoNXsHt40pz/dF62ujItBp7LaEQhkcn03ec7GkzXbmnSzQ14bm1XvFLGWybSZ7GkXgmimP5ngCXDtu/i57spUm+xS1BTetX5ck3WPg/LR5JvnW90cROG/9JGBDjotvASbY+IInL7e+K2OGhajFQtRlxy+b0Bd52d4U0rlbs3kgApV2bAIcypLADa/0loWIfTLdjoEIBO20GTUmXLhCUqtXbLaG9CddAkoaEUfghBmmvboefB1NHmDhCZL2S3odc5kt8nQH/LtgSEQCOdksoMESMig634ErQCfQZx+mlUCNFSpMvtNLaIcq698ChyPW/CUCZ5QcHXab+n7Ge+M15vGxk8VFoNcbtwPNViOCklwNzASWhuY8AV4C600/G1gO3AbOWLTcenl+HYiKQJC5eyRVxSRcUJ6vZxGp4HMtz49Akh+TKCwCVthPS4VdRj3AHeA+MB3YZBdWgA/AyGA592OSK4Ew8iM+ZgqAVUAd0AEcI+rP6D/+CoCf0HfCu9e1CkQAAAAASUVORK5CYII=');
  707. }
  708. #att-console{
  709. color: #23ade5;
  710. background-color: white;
  711. width: 250px;
  712. min-height: 48px;
  713. padding: 14px 8px 14px 8px;
  714. border-radius: 8px;
  715. }
  716. .att-console-title{
  717. margin:4px;
  718. }
  719. .att-input-range{
  720. width: 200px;
  721. margin-right: 10px;
  722. outline: none;
  723. }
  724. .att-input-value{
  725. width: 20px;
  726. text-align: center;
  727. border: 0px;
  728. border-bottom: 1px solid gray;
  729. outline: none;
  730. }
  731. .att-button{
  732. min-width: 80px;
  733. height: 24px;
  734. font-size: 12px;
  735. background-color: #23ade5;
  736. color: #fff;
  737. border-radius: 4px;
  738. border: 0px;
  739. margin-right: 2px;
  740. }
  741. .att-button:hover{
  742. background-color: #39b5e7;
  743. }
  744. .att-comment-span{
  745. background-color:rgba(0,0,0,0.4);
  746. position:relative;
  747. white-space: normal;
  748. border-radius: 3px;
  749. padding: 0 8px;
  750. text-align: center;
  751. line-height: normal;
  752. font-family: none;
  753. -webkit-box-decoration-break:clone;
  754. user-select: none;
  755. cursor: move;
  756. box-decoration-break: clone;
  757. vertical-align: middle;
  758. }
  759. #comment-container{
  760. z-index: 999;
  761. position:absolute;
  762. width:100%;
  763. text-align: center;
  764. }
  765. .att-comment-box{
  766. display: inline-block;
  767. vertical-align: middle;
  768. text-align: center;
  769.  
  770. }
  771. .att-comment-fixed{
  772. bottom: 71px;
  773. }
  774. .att-comment-float{
  775. left: auto;
  776. top:0px;
  777. }
  778.  
  779.  
  780. `
  781. $('body').append($('<style></style>').text(consoleStyle))
  782. })();

QingJ © 2025

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