Greasy Fork is available in English.

一帆视频去广告

一帆视频(原 "iF 视频"、"多瑙")去广告

2021/08/28時点のページです。最新版はこちら。

作者のサイトでサポートを受ける。または、このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==UserScript==
// @namespace   moe.jixun.dn-noad

// @name        一帆视频去广告
// @description 一帆视频(原 "iF 视频"、"多瑙")去广告

// @name:en        iFVOD no AD
// @description:en Remove AD on iFVOD (aka dnvod)

// @match       https://train.ifvod.tv/*
// @match       https://*.ifsp.tv/*
// @grant       none
// @version     2.1.6
// @author      Jixun Moe<https://jixun.moe/>
// @license     BSD-3-Clause
// @supportURL  https://jixun.moe/post/ifun-noad#respond
// @homepageURL https://jixun.moe/post/ifun-noad
// @compatible  Chrome   ViolentMonkey
// @run-at      document-start
// ==/UserScript==

//// Injection Parameter ////
const __DEBUG__ = false;
const id = 'jixun: have fun :D';

// M 变量所定义的模组加载完毕后的 CHUNK ID。
// 通常是用户处理模块加载完毕后就可以开始了。
const CHUNK_MAIN = 6;

const M = {
  InitUser:          'T1Vy',
  PermissionManager: 'xMFu',
  StoreState:        'AytR',
  URLHelper:         '3My9',
  LegacyRouteLoader: 'tyNb',
  RxJS:              'lJxs',
};
//// Injection Parameter ////


const s = document.createElement('style');
s.textContent = `

.cloppe {
  display: block !important;
}

.video-box {
  height: unset!important;
}

.danmu-center {
  min-height: 1005px !important;
  max-width: 300px !important;
}

app-gg-block, app-gg-block.d-block, .overlay-logo
{
  display: none !important;
}

`;
const addStyle = () => document.head.appendChild(s);
const defaultAvatar = 'https://static.{Host}/upload/up/20170815000037.jpg';

const always = v => ({
  get: () => v,
  set: () => {},
});

function generateIp() {
  const invoke = x => x();
  const v = () => (Math.random() * 255) | 0;
  return [v, v, v, v].map(invoke).join('.')
}

function getKeys(obj, keys) {
  let next = obj;
  for(let i = 0; i < keys.length; i++) {
    const key = keys[i];
    if (!next || !Object.prototype.hasOwnProperty.call(next, key)) {
      return null;
    }

    next = next[key];
  }
  return next;
}

function hookPlayerComponent(RxJS, proto) {
  // rxMap: https://rxjs.dev/api/operators/map
  const rxMap = RxJS.a;

  const cache = new Set();
  const { invokeDataToVideoPage } = proto;

  function patchVideoService(VideoService) {
    if (cache.has(VideoService)) {
      return;
    }
    cache.add(VideoService);
    
    const { getMedia } = VideoService.prototype;
    VideoService.prototype.getMedia = function () {
      return getMedia.apply(this, arguments).pipe(rxMap(media => {
        if (media.vipSeriesList) {
          return media;
        }

        return Object.assign({}, media, { vipSeriesList: [] });
      }));
    };
  }

  proto.invokeDataToVideoPage = function () {
    patchVideoService(this._videoService.constructor);
    return invokeDataToVideoPage.apply(this, arguments);
  };
}

function injectToLegacyRoute(require) {
  const RouteLoader = require(M.LegacyRouteLoader);
  const forChild = getKeys(RouteLoader, ['g', 'forChild']);
  if (!forChild) { return }

  RouteLoader.g.forChild = function (child) {
    const PlayerComponentProto = getKeys(child, [1, 'component', 'prototype']);
    if (PlayerComponentProto && PlayerComponentProto.invokeDataToVideoPage) {
      hookPlayerComponent(require(M.RxJS), PlayerComponentProto);
    }
    return forChild.apply(this, arguments);
  };
}

(window.webpackJsonp = window.webpackJsonp || []).push([
  [/* iF-vod 去广告 */],
  {
    [id]: function (module, exports, require) {
      addStyle();
      const idx = webpackJsonp.findIndex(x => x[1][id]);
      webpackJsonp.splice(idx, 1);
      const fakeIp = generateIp();

      const {a: PermissionManager} = require(M.PermissionManager);
      PermissionManager.prototype.isValid = () => true;

      const {a: StoreState} = require(M.StoreState);
      Object.defineProperty(StoreState, 'allVip', always(true));
      Object.defineProperty(StoreState, 'hideAds', always(true));
      Object.defineProperty(StoreState, 'disableNotify', always(true));

      const {a: URLHelper} = require(M.URLHelper);
      
      function updateUser(user) {
        Object.defineProperty(user, 'userName', always('某用户'));
        Object.defineProperty(user, 'nickName', always('某用户'));
        Object.defineProperty(user, 'endDays', always(1));

        Object.defineProperty(user, 'vipImage', always('jixun:normal-vip.png'));
        Object.defineProperty(user, 'sex', always(9));
        Object.defineProperty(user, 'nickName', always(''));
        Object.defineProperty(user, 'experience', always(0));
        Object.defineProperty(user, 'gold', always(0));
        Object.defineProperty(user, 'nextLevel', always(99));
        Object.defineProperty(user, 'gid', always(99));

        Object.defineProperty(user, 'lastIP', always(fakeIp));
        Object.defineProperty(user, 'from', always('地球'));
        Object.defineProperty(user, 'headImage', always(URLHelper.GetHost(defaultAvatar)));
      }
      
      // 过部分检测,如 2.0x 倍速
      // 但也有一些 VIP 功能不会弹窗提示而直接报错。
      function fixUser(user) {
        Object.defineProperty(user, 'daysOfMembership', always(1));
        return user;
      }
      
      const {a: InitUser} = require(M.InitUser);
      const { fromValidateToken, fromGetAuthorizedUserInfo } = InitUser.prototype;

      InitUser.prototype.fromValidateToken = function (user) {
        updateUser(user);
        return fixUser(fromValidateToken.apply(this, arguments));
      };

      InitUser.prototype.fromGetAuthorizedUserInfo = function (user) {
        updateUser(user);
        return fixUser(fromGetAuthorizedUserInfo.apply(this, arguments));
      };

      injectToLegacyRoute(require);

      if (__DEBUG__) {
        window.__require__ = require;
      }
    },
  },
  [[id, CHUNK_MAIN]]
]);

// 过广告屏蔽检测
Object.defineProperty(window, 'isAdsBlocked', always(false));