// ==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.5
// @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 = location.hostname.includes('ifsp.tv') ? 5 : 3;
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));