虎牙Plus

虎牙自动领取任务经验、开宝箱,复制直播流链接,简化页面,去广告, 夜间模式,自动进入剧场模式

目前为 2020-05-16 提交的版本。查看 最新版本

  1. 'use strict';
  2. // ==UserScript==
  3. // @name 虎牙Plus
  4. // @namespace http://tampermonkey.net/
  5. // @icon https://www.google.com/s2/favicons?domain=huya.com
  6. // @version 1.0.8
  7. // @description 虎牙自动领取任务经验、开宝箱,复制直播流链接,简化页面,去广告, 夜间模式,自动进入剧场模式
  8. // @author Francis
  9. // @match *://*.huya.com/*
  10. // @grant GM_setClipboard
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14. let $;
  15.  
  16. function addUi(){
  17. let style = document.createElement('style');
  18. style.appendChild(document.createTextNode(`
  19. span.copy-stream-link:after {
  20. display: none;
  21. position: absolute;
  22. content: "";
  23. right: -20px;
  24. top: 6px;
  25. width: 18px;
  26. height: 18px;
  27. overflow: hidden;
  28. background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA4RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0YjMyYjVhNy1jMThjLTg2NDItYjRlMy04NzdmMjFiZjkzZTciIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MEJCNDhFNEIxMDZBMTFFN0IzQUNGNTM3RTZBMjEyRTQiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MEJCNDhFNEExMDZBMTFFN0IzQUNGNTM3RTZBMjEyRTQiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKFdpbmRvd3MpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MmFlNTQ3NDgtZjlmZS04NjQwLTg0ZTgtMmY4ZTcwYjc2YTkyIiBzdFJlZjpkb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6NWE5YjI1YjQtZmE1ZC0xMWU2LWI1MmYtYWM2NWYxZGRlZjQ2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+KzIZ1wAAAz9JREFUeNqslm1IU1EYx5/dzSW+pWVZppimzV7pzZWVIhGFZiIEgmFlREGmH4qEJOhFqEVf+tCXviiCZC/4Icga0ocwIyURcmnO2ZIyM9+auqnb1NnzXM5sm7u719wffrC7c+7zP+fc55zzyDQN+0BEMiQNOYYcQBKRCNZmQr4iH5A6pBGZ8xVM4aONQwqRMmbiTVEMGkgpM9cgVYhDKKg3xSPNSIUPM29KZO80sxiSDDOQj0gK/L9SWIx0McMjSD0SCUsXxXiDHBUyVCG1iBL8JyWLqfI0lCPVSCj4WWtDN4ekxp6uZh7zWXpmid9sYfpzSkhbfwHU6/JBJuNSekZbCn+bOysUbJ+V+dNsTYgKspNvQmRQPMw4bKDt0gCaXcOmSgXLpER/GMnwC+2NLYD09eeBkylganoMajuuQt94u3PLpJNhlj/MgpUrISf5FsSF7+GfLfZheKIrhpHJ767dsshwv1gwGm3YstUwav3ltT0ufDea3eZNSeO2ATQrAdNUr2fXVDJM8j3yFZC76Q6sCk6AZ58vQ7/5i1u7OuYkZMQX4aD4JASzbRBq2i7h4Pq8hdvIuRzECxQdugUKd1ZB7PIdEKgIg/ztD/nfzizMSS6HQwkl82a2GQs8b78iZEaKEDy8t0ZlQmZSGci5gH+7WB4EedseQH33fdgVfYIfkFPTDismSCkMTRhB7LYwsRPfTQOWLrDOmPkldVUAFwjZqhseveegTl8OvWOfxNLBREva7a1laOIb1OiK+GwTU0PPI+gafislmQ1k2CTUSilNCUBZJ6SOwXpo6q2WunuayPCVrx5/pn6gaRGMWfth4bIbQGu4K3bJu+o1Gb5jN7WgaP89bruI++rn/H+UkS86r+PRZZdqRh6NHBvePbHetKz0TWnGJK1B4zYACSIPh/zw2Rh60LEjLtrXG/bZSdBjclhsQ6AbeLkYs1akmCbnvA9nkVN0BIq9OWEfgZa+p4sxo5gFzMPtxtcjeTQRP95UdhZTL1TTaJFcKTOVOLNcFtNn1aZlt3/rEsxaWQyt1LqUlkCNnEOMizAysnfUrssotfKmyrmSVdEHkePs7tzgUeobWalPafteqOJ26q8AAwB8rQG0tt5ioQAAAABJRU5ErkJggg==);
  29. background-size: 18px 18px;
  30. }
  31.  
  32. span.copy-stream-link.copy-success:after {
  33. display: block;
  34. }
  35.  
  36. .huya-plus-btn{
  37. display: block;
  38. padding:0 10px;
  39. color:#b08444;
  40. background:#FFD29E;
  41. border-radius:15px;
  42. margin-left: 30px;
  43. user-select: none;
  44. transition:all .5s;
  45. }
  46.  
  47. .huya-plus-btn:hover{
  48. color:#FFF;
  49. background:#ffa801;
  50. }
  51.  
  52. #huya-ab,
  53. .player-banner-gift,
  54. #player-marquee-wrap,
  55. .room-gg-chat,
  56. .room-mod-ggTop,
  57. #hy-nav-download,
  58. .hy-nav-kaibo,
  59. .hy-nav-item:nth-child(2),
  60. #J_roomGameBuy,
  61. .jump-to-phone,
  62. #week-star-btn,
  63. .g-gift,
  64. #J_bigStreamerStage
  65. {
  66. display:none !important;
  67. }
  68.  
  69. *{
  70. transition: background .5s;
  71. }
  72.  
  73. .night-mode .duya-header-wrap,
  74. .night-mode #main_col,
  75. .night-mode .room-hd-l,
  76. .night-mode .player-gift-wrap,
  77. .night-mode .chat-room__ft,
  78. .night-mode .jspPane,
  79. .night-mode #J_profileNotice>div,
  80. .night-mode .week-rank__btn,
  81. .night-mode .J_msg,
  82. .night-mode .chat-room__list,
  83. .night-mode .msg-nobleEnter,
  84. .night-mode .msg-nobleEnter>div,
  85. .night-mode .msg-nobleSpeak,
  86. .night-mode .player-face-arrow,
  87. .night-mode #player-gift-tip,
  88. .night-mode .jspVerticalBar,
  89. .night-mode .illegal-report,
  90. .night-mode .subscribe-hd.sub-on,
  91. .night-mode .huya-plus-btn,
  92. .night-mode #player-gift-tip bottom,
  93. .night-mode #player-gift-tip btn,
  94. .night-mode .fansBadge-box,
  95. .night-mode .nav-expand-list,
  96. .night-mode .tt-user-card,
  97. .night-mode .share-entrance,
  98. .night-mode .search-suggest,
  99. .night-mode .u-links,
  100. .night-mode .entrance-expand,
  101. .night-mode .gameBuy-bd,
  102. .night-mode .guide-to-app,
  103. .night-mode .chat-room__wrap,
  104. .night-mode #J_profileNotice,
  105. .night-mode .msg-onTVLottery,
  106. .night-mode .room-core,
  107. .night-mode .msg-noble
  108. {
  109. background-color: rgb(47, 48, 53) !important;
  110. }
  111.  
  112. .night-mode #J_box_msgOfKing,
  113. .night-mode .msg-of-king
  114. {
  115. background: rgb(47, 48, 53) !important;
  116. }
  117.  
  118. .night-mode .subscribe-hd.sub-on,
  119. .night-mode .huya-plus-btn,
  120. .night-mode .nav-expand-game dd a
  121. {
  122. background-color: #464646 !important;
  123. }
  124.  
  125. .night-mode .subscribe-hd.sub-on,
  126. .night-mode .huya-plus-btn,
  127. .night-mode .match-item
  128. {
  129. color: #8e8a8a !important;
  130. }
  131.  
  132. .night-mode .hy-nav-link,
  133. .night-mode .hy-nav-title,
  134. .night-mode .nav-user-title,
  135. .night-mode #J_roomTitle,
  136. .night-mode .msg,
  137. .night-mode .subscribe-hd.sub-on,
  138. .night-mode .huya-plus-btn,
  139. .night-mode .cont-item,
  140. .night-mode .week-rank__btn,
  141. .night-mode .week-rank-name,
  142. .night-mode .msg-nobleEnter,
  143. .night-mode .peo-name,
  144. .night-mode .search-item,
  145. .night-mode .history-bd .new-clickstat,
  146. .night-mode .from,
  147. .night-mode .to,
  148. .night-mode .nav-expand-game dd a,
  149. .night-mode .hy-header-match-preview-name,
  150. .night-mode #pub_msg_input,
  151. .night-mode #search-bar-input:focus,
  152. .night-mode .msg-noble,
  153. .night-mode #J_box_msgOfKing,
  154. .night-mode #J_hyUserCard .u-assets
  155. {
  156. color: #E7E7E7 !important;
  157. }
  158.  
  159. .night-mode .room-sidebar,
  160. .night-mode .duya-header-wrap,
  161. .night-mode .week-rank__unit,
  162. .night-mode .chat-room__input,
  163. .night-mode .chatNotice,
  164. .night-mode #J_profileNotice,
  165. .night-mode .plaer-face-icon-bg,
  166. .night-mode .chat-room__ft__chat,
  167. .night-mode #tipsOrchat
  168. {
  169. border-color: #3e3e3e !important;
  170. }
  171.  
  172. .night-mode .week-rank__btn.active,
  173. .night-mode #pub_msg_input,
  174. .night-mode #J_weekRankList li:hover,
  175. .night-mode #J_fansRankList li:hover,
  176. .night-mode .seat-item:hover,
  177. .night-mode #search-bar-input,
  178. .night-mode .search-item:hover,
  179. .night-mode .video-link:hover,
  180. .night-mode .history-bd .new-clickstat:hover,
  181. .night-mode .video-item:hover,
  182. .night-mode .match-item:hover,
  183. .night-mode .hy-header-match-preview li:hover
  184. {
  185. background-color: #565656 !important;
  186. }
  187.  
  188. .night-mode-btn-wrapper{
  189. float: left;
  190. position: relative;
  191. margin-left:15px;
  192. height: 100%;
  193. display: flex;
  194. align-items: center;
  195. justify-content: center;
  196. }
  197.  
  198. .night-mode-switch-btn{
  199. width: 50px;
  200. border: 1px solid #e4e4e4;
  201. height: 26px;
  202. border-radius: 13px;
  203. background-color:#ff8a00;
  204. }
  205.  
  206. .night-mode-switch-dot{
  207. width: 24px;
  208. height: 24px;
  209. border-radius: 12px;
  210. background: #FFF;
  211. line-height: 24px;
  212. border:1px solid #b1b1b1;
  213. text-align: center;
  214. color: #6b6b6b;
  215. transition: all .5s;
  216. cursor: pointer;
  217. user-select:none;
  218. }
  219.  
  220. .night-mode .night-mode-switch-btn{
  221. background-color:#8c8c8c;
  222. }
  223.  
  224. .night-mode .night-mode-switch-dot{
  225. transform: translateX(24px);
  226. }
  227. `));
  228.  
  229. document.head.appendChild(style);
  230.  
  231. let copyStreamLinkNode = document.createElement('div');
  232. copyStreamLinkNode.style = "cursor: pointer;display:inline-flex;vertical-align:top;";
  233. const openWithPlayerBtn = isMacOS() ? `<span class="huya-plus-btn open-with-iina" style="position: relative;">使用IINA打开</span>`: `<span class="huya-plus-btn open-with-potplayer" style="position: relative;">使用PotPlayer打开</span>`;
  234. copyStreamLinkNode.innerHTML = `<span class="huya-plus-btn copy-stream-link" style="position: relative;">复制直播流</span>${openWithPlayerBtn}`;
  235. document.querySelector('.host-title').appendChild(copyStreamLinkNode);
  236.  
  237. document.querySelector('.copy-stream-link').onclick = e=>{
  238. GM_setClipboard(getStreamUrl());
  239. showCopySuccessIcon();
  240. };
  241.  
  242. $(".open-with-iina").click(()=>{
  243. openStreamWithIINA(getStreamUrl());
  244. });
  245.  
  246. $(".open-with-potplayer").click(()=>{
  247. openStreamWithPotPlayer(getStreamUrl());
  248. });
  249. }
  250.  
  251. function getStreamUrl(){
  252. let config = unsafeWindow.hyPlayerConfig;
  253. try{
  254. let info = config.stream.data[0].gameStreamInfoList[0]
  255. return `${info.sHlsUrl}/${info.sStreamName}.${info.sHlsUrlSuffix}?${info.sHlsAntiCode}`;
  256. }catch(e){
  257. alert("获取直播流链接失败,房间未开播或刷新页面后重试")
  258. throw e;
  259. }
  260. }
  261.  
  262. function isMacOS(){
  263. var UserAgent = navigator.userAgent.toLowerCase();
  264. return /mac os/.test(UserAgent);
  265. }
  266.  
  267. function showCopySuccessIcon(){
  268. $('span.copy-stream-link').addClass('copy-success');
  269. setTimeout(()=>{$('span.copy-stream-link').removeClass('copy-success');},1000)
  270. }
  271.  
  272. function autoReceiveBoxReward(){
  273. let rewardBtns = $(".player-box-list .player-box-stat3").filter((i,it)=>$(it).css("visibility") === 'visible');
  274. if(rewardBtns.size() > 0){
  275. let btn = $(rewardBtns[0]);
  276. btn.click();
  277. let waitComplete = ()=>{
  278. if(btn.css("visibility") === 'hidden'){
  279. $("#player-box").hide();
  280. console.log("开启宝箱");
  281. autoReceiveBoxReward();
  282. } else {
  283. setTimeout(waitComplete,1000);
  284. }
  285. };
  286. setTimeout(waitComplete,1000);
  287. }
  288. }
  289.  
  290. function autoReceiveTaskXP(){
  291. let taskBtns = $(".tasks .status .status-get");
  292. if(taskBtns.size() > 0){
  293. $.each(taskBtns,(_,btn)=>{
  294. $(btn).click();
  295. });
  296. console.log(`自动领取经验,本次完成${taskBtns.length}个任务`)
  297. }
  298. }
  299.  
  300. function cleanPage(){
  301. $(".room-gg-chat").remove();
  302. $(".room-footer").remove();
  303. }
  304.  
  305. function completeChatTask(){
  306. const taskInfo = $(".tasks .tit").filter((i,it)=>$(it).text() === '在1场直播中发送弹幕');
  307. const taskDone = taskInfo.siblings(".status").find(".status-ing").size() === 0;
  308. if(!taskDone){
  309. chat('[送花]')
  310. }
  311. }
  312.  
  313. function chat(msg){
  314. $("#pub_msg_input").val(msg).keyup();
  315. $("#msg_send_bt").click();
  316. }
  317.  
  318. function pageLoaded(){
  319. $ = unsafeWindow.$
  320. if($){
  321. if($(".tasks .status").size() == 0){
  322. $(".nav-user-title").mouseenter()
  323. }
  324. return $(".box-icon-word").size() > 0 && $(".tasks .status").size() > 0
  325. }
  326. return false;
  327. }
  328.  
  329. function openStreamWithPotPlayer(streamUrl){
  330. openStreamWithPlayer("PotPlayer://", streamUrl);
  331. }
  332.  
  333. function openStreamWithIINA(streamUrl){
  334. openStreamWithPlayer("iina://weblink?url=", streamUrl)
  335. }
  336.  
  337. function openStreamWithPlayer(playerUrlSchema, streamUrl){
  338. window.open(`${playerUrlSchema}${streamUrl}`, "_self")
  339. }
  340.  
  341. async function waitLoad(){
  342. return new Promise(function(resolve,reject){
  343. let w = ()=>{
  344. if(pageLoaded()){
  345. resolve();
  346. } else {
  347. setTimeout(w,1000);
  348. }
  349. }
  350. w();
  351. });
  352. }
  353.  
  354. function nightMode(){
  355. $("#J_global_user_tips").before(`
  356. <div class="night-mode-btn-wrapper">
  357. <div class="night-mode-switch-btn">
  358. <div class="night-mode-switch-dot">日</div>
  359. </div>
  360. </div>
  361. `)
  362.  
  363. let switchDay = ()=>{
  364. $(".night-mode-switch-dot").text("日");
  365. document.body.classList.remove('night-mode');
  366. localStorage.setItem("night-mode",false);
  367. }
  368.  
  369. let switchNight = ()=>{
  370. $(".night-mode-switch-dot").text("夜");
  371. document.body.classList.add('night-mode');
  372. localStorage.setItem("night-mode",true);
  373. }
  374.  
  375. $(".night-mode-switch-btn").click(()=>{
  376. if(document.body.classList.contains("night-mode")){
  377. switchDay();
  378. } else {
  379. switchNight();
  380. }
  381. })
  382.  
  383. if(localStorage.getItem("night-mode") === 'true'){
  384. switchNight();
  385. }
  386. }
  387.  
  388. // 自动领取礼物掉落的宝箱
  389. let receiveTimer;
  390. function autoReceiveTreasure(){
  391. if($("#J_treasureChestContainer .btn").size() === 0){
  392. return;
  393. }
  394. let receive = ()=>{
  395. if($("#J_treasureChestContainer .btn.usable").size() > 0){
  396. $("#J_treasureChestContainer .btn.usable").click()
  397. clearInterval(receiveTimer);
  398. receiveTimer = undefined;
  399. } else if($("#J_treasureChestContainer .btn").size() > 0) {
  400. chat('[送花]')
  401. } else {
  402. clearInterval(receiveTimer);
  403. receiveTimer = undefined;
  404. }
  405. }
  406. if(!receiveTimer){
  407. receiveTimer = setInterval(receive,1000);
  408. }
  409. }
  410.  
  411. let timer,treasureTimer;
  412. (async function() {
  413. let intervalInMills = 10 * 60 * 1000 + 100;
  414. let task = ()=>{
  415. autoReceiveBoxReward();
  416. autoReceiveTaskXP();
  417. };
  418. await waitLoad();
  419.  
  420. cleanPage();
  421. nightMode();
  422. $(".player-fullpage-btn").click();
  423. completeChatTask();
  424. addUi();
  425. task();
  426. if(timer) clearInterval(timer);
  427. timer = setInterval(task,intervalInMills);
  428. if(treasureTimer) clearInterval(treasureTimer)
  429. treasureTimer = setInterval(autoReceiveTreasure, 30000)
  430. })();

QingJ © 2025

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