Greasy Fork is available in English.

acfun直播弹幕

acfun直播弹幕。

Tính đến 2020-11-02 16:00:27 UTC. Xem phiên bản mới nhất.

// ==UserScript==
// @name     acfun直播弹幕
// @description acfun直播弹幕。
// @namespace syachiku
// @author       syachiku
// @match        https://live.acfun.cn/live/*
// @grant		GM_addStyle
// @grant GM_getResourceURL
// @grant   GM_xmlhttpRequest
// @version  1.1.2
// @require https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/clipboard-polyfill/3.0.1/promise/clipboard-polyfill.promise.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/noty/3.1.4/noty.min.js
// ==/UserScript==



;(async function(){

	const css = `
		/* base html */
		#header,#footer,
		.main>.list-container.outer-wrapper,
		.main>.list-container.outer-wrapper:before,
		.container-live>.left,
		.live-feed-watching,
		.container-live-feed-messages:before
		{display:none!important}
		#app>.main,
		.player-outer-wrapper,
		.player-outer-wrapper>.container-live,
		.player-outer-wrapper>.container-live>.container-live-feed.right,
		.player-outer-wrapper>.container-live>.container-live-feed.right>.live-feed,
		.player-outer-wrapper>.container-live>.container-live-feed.right>.live-feed>.container-live-feed-messages,
		.player-outer-wrapper>.container-live>.container-live-feed.right>.live-feed>.container-live-feed-messages>.live-feed-messages
		{
		display:block!important;
		position:fixed!important;
		width:100%!important;
		height:100%!important;
		margin:0!important;
		padding:0!important;
		border:0!important;
		top:0!important;
		bottom:0!important;
		word-break:break-all!important;
		}
		.player-outer-wrapper>.container-live>.container-live-feed.right>.live-feed>.container-live-feed-messages{background:#0c0!important;}
		.player-outer-wrapper>.container-live>.container-live-feed.right>.live-feed>.container-live-feed-messages>.live-feed-messages{height:calc(100% - 5px)!important}
		/* danmu */
		.live-feed-messages>div{
		height:auto!important;
		line-height:30px!important;
		font-size:120%!important;
		font-weight:900!important;
		margin-left:5px!important;
		font-family:Microsoft Yahei!important;
		margin-bottom:3px!important;
		}
		.container-live-feed-messages .live-feed-messages>div>div{
		text-shadow: 0px 2px 2px #000, 0px -2px 2px #000, 2px 0px 2px #000, -2px 0px 2px #000, 2px 2px 2px #000, -2px -2px 2px #000, 2px -2px 2px #000, -2px 2px 2px #000!important;
		padding:1px 5px 1px 1px!important;max-width:unset!important;
		}
		.container-live-feed-messages .live-feed-messages>div>div>:nth-child(1){color:#b6d9fa!important}
		.container-live-feed-messages .live-feed-messages>div>div>:nth-child(2){color:#fff!important}
		.container-live-feed-messages .live-feed-messages>div>div>.nickname{text-overflow:unset!important;overflow:visible!important;max-width:unset!important;}
		.container-live-feed-messages .live-feed-messages>:not(.comment)>div>:nth-child(2){color:#ddd!important}
		.container-live-feed-messages .live-feed-messages>:not(.comment)>div>span:nth-child(1){margin-right:10px!important;}
		.container-live-feed-messages .live-feed-messages>.comment{padding:1px 0px 1px 0px!important;margin:0 0 -5px 0px!important}
		.container-live-feed-messages .live-feed-messages>.comment>div{line-height:24px!important;padding:0px 10px 0px 4px!important;margin:0px 0 0 8px!important}
		.container-live-feed-messages .live-feed-messages>.like{padding:0px 0px 2px 10px!important;}
		.container-live-feed-messages .live-feed-messages>.like>div{padding:2px 18px 2px 10px!important;margin:0 0 0 -12px!important;border-radius:10px!important}
		.container-live-feed-messages .live-feed-messages>.like>div>span:after{padding:0px 5px 0px 5px!important;margin:0px -10px 0 10px!important}
		.container-live-feed-messages .live-feed-messages>.follow>div{height:auto!important;padding:2px 10px 3px 7px!important;margin:3px 0px 4px 0!important}
		.container-live-feed-messages .live-feed-messages>.user-enter>div{height:auto!important;padding:2px 10px 3px 4px!important;margin:3px 0 1px 3px!important;border-radius:10px!important}
		.container-live-feed-messages .live-feed-messages>.gift>div{background:#fedf3b!important;height:auto!important;line-height:25px!important;padding:2px 5px 2px 10px!important;margin:0 0 -5px 0!important;border-radius:10px!important}
		.container-live-feed-messages .live-feed-messages>.gift>div>span:nth-child(2){padding:0px 5px 0px 0px!important;}
		.container-live-feed-messages .live-feed-messages>.gift>div>img{margin:0 0 1px 0!important}

    .container-live-feed-messages .live-feed-messages >div{
      cursor: pointer;
      background-size: 200.22% auto;
      -webkit-background-size: 200.22% auto;
      -moz-background-size: 200.22% auto;
      background-position: 0% 0;
      background-image: linear-gradient(to right, rgba(255, 255, 255, 0) 50%, #1890ff 50%);
      text-decoration: none;
      transition: background-position 0.5s ease-out;
      -webkit-transition: background-position 0.5s ease-out;
    }
    .container-live-feed-messages .live-feed-messages >div:hover{
      background-position: -99.99% 0;
    }
		.container-live-feed-messages .live-feed-messages > :not(.comment) > div > :nth-child(2).nickname{
		    color : #b6d9fa !important
		}
		.container-live-feed-messages .live-feed-messages > div > div > :nth-child(2).nickname{
		    color : #b6d9fa !important
		}
		.container-live-feed-messages .live-feed-messages > :not(.comment) > div > :nth-child(2){
		    color:#fff !important;
		}
		.container-live-feed-messages .live-feed-messages > div.comment > div .comment-text{
		    color:#fff !important;
		}
		.container-live-feed-messages .live-feed-messages > div.like > div .like-text{
		    color:#fff !important;
		}
		.container-live-feed-messages .live-feed-messages > div.gift > div{
		    color : #fff !important;
		}
		.container-live-feed-messages .live-feed-messages > div.user-enter{
			color: #fff !important;
		}
    .container-live-feed-messages .live-feed-messages .vup.vup-user{
        position: relative;
        display: inline-block;
        padding: 0 8px;
        background: #409bef;
        border-radius: 9px;
        color: white !important;
        height: 18px;
        line-height: 18px;
    }
		.live-feed-input{
		    display : none !important;
		}
		/*.live-feed-input:hover{
		    opacity : 1;
		}*/



	`;

	GM_addStyle(css);
  
  
  const config = {
    SERVER : 'http://47.112.178.125',
    URLS : {
      ACFUN_USER : {
        VUP : '/user/acfun_user_info_simplified',
      },
    },
    RESPONSE : {
      FIELD : {
        STATUS : 'code',
			  MSG : 'message',
			  DATA : 'data',
      },
      STATUS : {
        SUCCESS : 200,
      }
    }
  };

  // 禁止播放视频
  function disableVideos(){
    window.setInterval(function(){
      let videoEles = document.querySelectorAll('video');
      for(let videoEle of videoEles){
        videoEle.src = null;
      }
    }, 500);

  }
  
  // 是否为空
  function isNullOrEmpty(val){
    return _.isUndefined(val) || _.isNull(val) || _.isNaN(val) || (((_.isObject(val) && !_.isDate(val)) || _.isArray(val) || _.isString(val)) && _.isEmpty(val))
  }
  
  // 通用请求
  function commonRequrest(url, method, data, raw, callback){
    var isSuccess = false;
    var data = null;
    GM_xmlhttpRequest({
      synchronous : !_.isFunction(callback),
      method : method,
      url : url,
      data : data,
      onload : function(res){
        
        // 200
        if(res.status==200){
          if(raw){
            callback(true, res.responseText);
          }
          else{
            res = JSON.parse(res.responseText);
            isSuccess = res[config.RESPONSE.FIELD.STATUS] == config.RESPONSE.STATUS.SUCCESS;
            data = res[config.RESPONSE.FIELD.DATA];

            if(_.isFunction(callback)){
              callback(isSuccess, data);
            }
          }
        }
      },
      onerror : function(){
        if(_.isFunction(callback)){
          callback(isSuccess, data);
        }
      },
    });
      
    return [isSuccess, data];
  }
  
  function addCssResource(url){
    
    commonRequrest(url, 'get', null, true, function(isSuccess, css){
      if(isSuccess){
        GM_addStyle(css);
      }
    })
  }
  
  // 添加提醒样式
  addCssResource('https://cdnjs.cloudflare.com/ajax/libs/noty/3.1.4/noty.min.css');
  
  // 添加vup徽章
  function addVupSign(){
    
    function addBadgeToUser(userEle){
      var badgeNode = document.createElement('span');
      badgeNode.className = 'vup vup-user';
      badgeNode.innerText = 'VUP';
      userEle.parentNode.insertBefore(badgeNode, userEle.parentNode.childNodes[0]);
    }
    
    const acSeriesPattern = new RegExp('(?:a|A)(?:c|C)\s*(\d+)');
    function extractAcSeries(text){
      var match = text.match(acSeriesPattern);
      if(match){
        return parseInt(match[match.length-1]);
      }
      else{
        return null;
      }
    }
    
    
    // 获取vup列表
    commonRequrest(config.SERVER + config.URLS.ACFUN_USER.VUP, 'GET', null, false, function(isSuccess, data){
      // 获取失败
      if(!isSuccess){
        return
      }
      
      var vupInfo = {};
      data.forEach(function(item){
        vupInfo[item.uid] = item;
      });
      
      // 监听弹幕添加
      var messageContainer = document.querySelector('.live-feed-messages');
      var observer = new MutationObserver(function(mutations, observer){
        // 遍历改变
        mutations.forEach(function(mutation){
          // 子节点发生变化
          if(mutation.type == 'childList'){
            
            // 遍历新增节点
            mutation.addedNodes.forEach(function(node){
              
              // 获取用户名元素
              var userEle = node.querySelector('.nickname');
              
              // 添加点击事件
              node.addEventListener('click', function(event){
                var userName = userEle.innerText;
                // 弹幕
                if(node.classList.contains('comment')){
                  // 获取弹幕内容
                  var comment = _.trimStart(node.querySelector('.comment-text').innerText, ':');
                  var acSeries = extractAcSeries(comment);
                  
                  // 普通文本
                  if(isNullOrEmpty(acSeries)){
                    clipboard.writeText(comment);
                    new Noty({
                      type : 'info',
                      layout : 'topCenter',
                      timeout : 2000,
                      text : '已复制弹幕:' + comment,
                    }).show();
                  }
                  // 如果有ac号
                  else{
                    clipboard.writeText(acSeries);
                    new Noty({
                      type : 'info',
                      layout : 'topCenter',
                      timeout : 2000,
                      text : '已复制ac号:' + acSeries,
                    }).show();
                  }
                  
                }
                // 其他类型
                else{
                  clipboard.writeText(userName);
                  
                  new Noty({
                      type : 'info',
                      layout : 'topCenter',
                      timeout : 2000,
                    text : '已复制用户名:' + userName
                  }).show();
                }
              });
              
              if(userEle && userEle.attributes['data-user-id']){
                var uid = parseInt(userEle.attributes['data-user-id'].value);
                
                // vup
                if(uid in vupInfo){
                  addBadgeToUser(userEle);
                }
                
              }
            });
          }
        });
      });
      observer.observe(messageContainer, {childList:true});
      
    });
  }
  

  
  disableVideos();
  
  window.onload = function(){
    addVupSign();  
  };
  
  
  
})();