Bilibili - Whose Bullets

为您探寻到那些弹幕后的作者

当前为 2018-04-07 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Bilibili - Whose Bullets
  3. // @namespace http://www.xljbear.com/
  4. // @version 1.4
  5. // @description 为您探寻到那些弹幕后的作者
  6. // @author XljBearSoft
  7. // @match https://www.bilibili.com/video/av*
  8. // @match https://www.bilibili.com/bangumi/play/*
  9. // @icon https://www.bilibili.com/favicon.ico
  10. // @supportURL https://greasyfork.org/zh-CN/scripts/40341
  11. // @grant none
  12. // ==/UserScript==
  13. (function() {
  14. page_url = window.location.href;
  15. setTimeout(WhoseBulletsInit,1000);
  16. })();
  17. var BiliBili_midcrc = function(){
  18. const CRCPOLYNOMIAL = 0xEDB88320;
  19. var startTime=performance.now(),
  20. crctable=new Array(256),
  21. create_table=function(){
  22. var crcreg,
  23. i,j;
  24. for (i = 0; i < 256; ++i)
  25. {
  26. crcreg = i;
  27. for (j = 0; j < 8; ++j)
  28. {
  29. if ((crcreg & 1) !== 0)
  30. {
  31. crcreg = CRCPOLYNOMIAL ^ (crcreg >>> 1);
  32. }
  33. else
  34. {
  35. crcreg >>>= 1;
  36. }
  37. }
  38. crctable[i] = crcreg;
  39. }
  40. },
  41. crc32=function(input){
  42. if(typeof(input)!='string')
  43. input=input.toString();
  44. var crcstart = 0xFFFFFFFF, len = input.length, index;
  45. for(var i=0;i<len;++i){
  46. index = (crcstart ^ input.charCodeAt(i)) & 0xff;
  47. crcstart = (crcstart >>> 8) ^ crctable[index];
  48. }
  49. return crcstart;
  50. },
  51. crc32lastindex=function(input){
  52. if(typeof(input)!='string')
  53. input=input.toString();
  54. var crcstart = 0xFFFFFFFF, len = input.length, index;
  55. for(var i=0; i<len;++i){
  56. index = (crcstart ^ input.charCodeAt(i)) & 0xff;
  57. crcstart = (crcstart >>> 8) ^ crctable[index];
  58. }
  59. return index;
  60. },
  61. getcrcindex=function(t){
  62. for(var i=0;i<256;i++){
  63. if(crctable[i] >>> 24 == t)
  64. return i;
  65. }
  66. return -1;
  67. },
  68. deepCheck=function(i, index){
  69. var tc=0x00,str='',
  70. hash=crc32(i);
  71. tc = hash & 0xff ^ index[2];
  72. if (!(tc <= 57 && tc >= 48))
  73. return [0];
  74. str+=tc-48;
  75. hash = crctable[index[2]] ^ (hash >>> 8);
  76. tc = hash & 0xff ^ index[1];
  77. if (!(tc <= 57 && tc >= 48))
  78. return [0];
  79. str+=tc-48;
  80. hash = crctable[index[1]] ^ (hash >>> 8);
  81. tc = hash & 0xff ^ index[0];
  82. if (!(tc <= 57 && tc >= 48))
  83. return [0];
  84. str+=tc-48;
  85. hash = crctable[index[0]] ^ (hash >>> 8);
  86. return [1,str];
  87. };
  88. create_table();
  89. var index=new Array(4);
  90. return function(input){
  91. var ht=parseInt('0x'+input)^0xffffffff,
  92. snum,i,lastindex,deepCheckData;
  93. for(i=3;i>=0;i--){
  94. index[3-i]=getcrcindex( ht >>> (i*8) );
  95. snum=crctable[index[3-i]];
  96. ht^=snum>>>((3-i)*8);
  97. }
  98. for(i=0;i<10000000; i++){
  99. lastindex = crc32lastindex(i);
  100. if(lastindex == index[3]){
  101. deepCheckData=deepCheck(i,index);
  102. if(deepCheckData[0])
  103. break;
  104. }
  105. }
  106. if(i==10000000)
  107. return -1;
  108. return i+''+deepCheckData[1];
  109. };
  110. };
  111. var page_url = "";
  112. var b_crc = null;
  113. var ToastTime = null;
  114. var crcidList = [];
  115. var menu = '<li class="context-line context-menu-function gotoSpace" data-append="1"><a class="context-menu-a js-action gotoSpace" title="" href="javascript:void(0);" data-disabled="0"><span>正在获取...</span></a></li>';
  116. var menu_fail = '<li class="context-line context-menu-function" data-append="1"><a class="context-menu-a js-action" title="" href="javascript:void(0);" data-disabled="0">- (゜ロ゜;)抱歉!居然失败了... -</a></li>';
  117. var toast = '<div id="x_toast" style="box-shadow: white 0px 0px 3px;" class="player-tooltips info center-center animation active"><div class="tooltip" style="padding:15px 20px 15px 20px;"></div></div>';
  118. function CreateMessageBox(){
  119. var html = '<div id="x_message_box" style="background-color: black;font-size: 13px;color: white;text-align: center;padding: 10px;"></div>';
  120. $(".bilibili-player-area").prepend(html);
  121. $("#x_message_box").hide();
  122. }
  123. function ShowMessage(message){
  124. if(!$("#x_message_box")[0])CreateMessageBox();
  125. $("#x_message_box").slideDown(500);
  126. $("#x_message_box").html("Whose Bullets : " + message);
  127. setTimeout(HideMessage,3000);
  128. }
  129. function HideMessage(){
  130. $("#x_message_box").slideUp(500);
  131. }
  132. function GetAuthorProfile(mid){
  133. $.post("https://space.bilibili.com/ajax/member/GetInfo",{mid:mid},function(result){
  134. switch(result.data.sex){
  135. case "男":
  136. sex = '<span style="color:#00a1d6">汉子</span>';
  137. break;
  138. case "女":
  139. sex = '<span style="color:#fb7299">妹纸?</span>';
  140. break;
  141. default:
  142. sex = '<span style="color:#ff6c00">秀吉</span>';
  143. }
  144. vip = result.data.vip.vipStatus==1?" vip-red-name":"";
  145. place = result.data.place==""||result.data.place==undefined?"无地区信息":result.data.place;
  146. profile = '<div style="min-height:0px;z-index:-5;" class="bb-comment"><div style="padding-top:10px;" class="comment-list"><div class="list-item"><div class="reply-box"><div style="padding:0px" class="reply-item reply-wrap"><div style="margin:15px;" class="reply-face"><img src="'+ result.data.face +'" alt=""></div><div class="reply-con"><div class="user"><a style="display:initial;padding: 0px;" data-usercard-mid="'+ mid +'" href="//space.bilibili.com/'+ mid +'" target="_blank" class="name'+ vip +'">'+ result.data.name +'</a> '+ sex +'<a style="display:initial;padding: 0px;" href="//www.bilibili.com/blackboard/help.html#%E4%BC%9A%E5%91%98%E7%AD%89%E7%BA%A7%E7%9B%B8%E5%85%B3" target="_blank"><i class="level l'+ result.data.level_info.current_level +'"></i></a></div><div class="info"><span class="time">'+ place +'</span></span></span></div></div></div></div></div></div></div>';
  147. $(".context-menu-function.gotoSpace").html(profile);
  148. if($(".bilibili-player-context-menu-container.white.active>ul>li:eq(1)>a").html().substr(0,2)=="取消"){
  149. $(".bilibili-player-context-menu-container.white.active>ul>li:eq(1)>a").html("取消对" + result.data.name + "的弹幕屏蔽");
  150. }else{
  151. $(".bilibili-player-context-menu-container.white.active>ul>li:eq(1)>a").html("屏蔽" + result.data.name);
  152. }
  153. $(".bilibili-player-context-menu-container.white.active>ul>li:eq(4)>a").html("查看"+ result.data.name +"的所有弹幕");
  154. });
  155. }
  156. function PageReload(){
  157. if(page_url == window.location.href)
  158. return;
  159. page_url =window.location.href;
  160. ShowToast("重载视频信息中...");
  161. crcidList = [];
  162. $.ajax({
  163. url:"https://comment.bilibili.com/" + window.cid + ".xml",
  164. dataType:"XML",
  165. success: function(danmu_xml){
  166. $(danmu_xml).find("d").each(function(index,item){
  167. crcid = $(item).attr("p").split(",")[6];
  168. crcidList[index] = crcid;
  169. });
  170. if(crcidList.length>0){
  171. ShowToast(crcidList.length + "条弹幕处理成功!");
  172. }else{
  173. ShowToast("弹幕库处理失败!");
  174. }
  175. }
  176. });
  177. }
  178. function ShowToast(message){
  179. if(!$("#x_toast")[0]){
  180. $("body").append(toast);
  181. }
  182. $("#x_toast>div").html("Whose Bullets : " + message);
  183. $("#x_toast").css("top",document.documentElement.clientHeight/2 - $("#x_toast")[0].offsetHeight/2 + "px");
  184. $("#x_toast").css("left",document.documentElement.clientWidth/2 - $("#x_toast")[0].offsetWidth/2 + "px");
  185. $("#x_toast").hide();
  186. $("#x_toast").fadeIn(500);
  187. clearTimeout(ToastTime);
  188. ToastTime = setTimeout(function(){$("#x_toast").fadeOut(1000);},3000);
  189. }
  190. function WhoseBulletsInit(){
  191. ShowToast("初始化弹幕库...");
  192. b_crc = new BiliBili_midcrc();
  193. $.ajax({
  194. url:"https://comment.bilibili.com/" + window.cid + ".xml",
  195. dataType:"XML",
  196. success: function(danmu_xml){
  197. $(danmu_xml).find("d").each(function(index,item){
  198. crcid = $(item).attr("p").split(",")[6];
  199. crcidList[index] = crcid;
  200. });
  201. if(crcidList.length>0){
  202. $(document).on("contextmenu",".danmaku-info-row.bpui-selected",function(){
  203. if($(".bilibili-player-danmaku-wrap-child").css("display")!="none")
  204. return;
  205. cid = $(this).attr("dmno");
  206. mid = b_crc(crcidList[cid]);
  207. if(mid == -1){
  208. ShowToast("嗷~用户信息获取失败了...");
  209. $(".bilibili-player-context-menu-container.white.active>ul").prepend(menu_fail);
  210. return;
  211. }
  212. $(".bilibili-player-context-menu-container.white.active>ul").prepend(menu).attr("mid",mid);
  213. $(".bilibili-player-context-menu-container.white.active").css("z-index","99");
  214. GetAuthorProfile(mid);
  215. });
  216. $(document).on("click","a.gotoSpace",function(){
  217. mid = $(this).parent().parent().attr("mid");
  218. window.open("https://space.bilibili.com/"+ mid +"/#/");
  219. });
  220. $(document).on("contextmenu",".bilibili-player-video",function(){
  221. //Todo
  222. });
  223. setInterval(PageReload,1000);
  224. ShowToast(crcidList.length + "条弹幕处理成功!");
  225. }else{
  226. ShowToast("弹幕库处理失败!");
  227. }
  228. }
  229. });
  230. }