Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
parent
0729e4f84d
commit
b56be38431
3 changed files with 46 additions and 31 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name M3U8 HLS Downloader
|
// @name M3U8 HLS Downloader
|
||||||
// @namespace http://tampermonkey.net/
|
// @namespace http://tampermonkey.net/
|
||||||
// @version 1.0.3
|
// @version 1.0.4
|
||||||
// @description 자동 탐지 및 다운로드: HLS(m3u8) 스트림의 세그먼트를 병합하여 단일 파일로 저장
|
// @description 자동 탐지 및 다운로드: HLS(m3u8) 스트림의 세그먼트를 병합하여 단일 파일로 저장
|
||||||
// @author kyush
|
// @author kyush
|
||||||
// @match *://*/*
|
// @match *://*/*
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "m3u8-monkey-script",
|
"name": "m3u8-monkey-script",
|
||||||
"version": "1.0.3",
|
"version": "1.0.4",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
||||||
73
src/index.ts
73
src/index.ts
|
|
@ -295,42 +295,57 @@ function onStreamDetected(url: string, headers?: Record<string, string>): void {
|
||||||
if (typeof window === 'undefined') {
|
if (typeof window === 'undefined') {
|
||||||
log.error('Script not running in a browser context');
|
log.error('Script not running in a browser context');
|
||||||
} else {
|
} else {
|
||||||
// Anti-devtool: debugger statement 차단
|
// Anti-devtool: devtools-detector 우회
|
||||||
|
// Source: https://greasyfork.org/en/scripts/456011-%E5%8F%8D-devtools-detector-%E5%8F%8D%E8%B0%83%E8%AF%95/code
|
||||||
|
// Targets: https://github.com/AEPKILL/devtools-detector
|
||||||
|
// Mechanism: Hooks Object.prototype.launch setter to intercept devtoolsDetector.launch.
|
||||||
|
// When the detector sets its launch method (containing '_detectLoopDelay'), it is
|
||||||
|
// replaced with a no-op that deletes the prototype-level launch and restores the
|
||||||
|
// original, preventing the debugger loop from executing.
|
||||||
(function() {
|
(function() {
|
||||||
const originalEval = window.eval;
|
const noop = function() {};
|
||||||
window.eval = function(code: any) {
|
|
||||||
if (typeof code === 'string' && code.includes('debugger')) {
|
|
||||||
code = code.replace(/debugger/g, '');
|
|
||||||
}
|
|
||||||
return originalEval.call(window, code);
|
|
||||||
};
|
|
||||||
|
|
||||||
const originalFunction = Function;
|
function disableLaunch(alt: () => void) {
|
||||||
(window as any).Function = function(...args: any[]) {
|
log.info('anti-devtool: disabling devtoolsDetector.launch');
|
||||||
if (args.length > 0) {
|
|
||||||
args[args.length - 1] = args[args.length - 1].replace(/debugger/g, '');
|
|
||||||
}
|
|
||||||
return originalFunction.apply(this, args);
|
|
||||||
};
|
|
||||||
(window as any).Function.prototype = originalFunction.prototype;
|
|
||||||
|
|
||||||
const originalLocation = Object.getOwnPropertyDescriptor(window, 'location');
|
const map = new Map<any, any>();
|
||||||
let locationBlocked = false;
|
|
||||||
|
|
||||||
window.addEventListener('beforeunload', function(e) {
|
const func = function() {
|
||||||
if (locationBlocked) {
|
delete (Object as any).prototype.launch;
|
||||||
e.preventDefault();
|
Object.getPrototypeOf(this).launch = alt;
|
||||||
|
this.launch();
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.defineProperty(Object.prototype, 'launch', {
|
||||||
|
set(f: any) {
|
||||||
|
const checked = funcChecked(f);
|
||||||
|
map.set(this, checked ? func : f);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
get() {
|
||||||
|
return getVal(this);
|
||||||
|
|
||||||
|
function getVal(obj: any): any {
|
||||||
|
return obj ? (map.has(obj) ? map.get(obj) : getVal(Object.getPrototypeOf(obj))) : undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
configurable: true,
|
||||||
|
enumerable: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
function funcChecked(f: any): boolean {
|
||||||
|
if (f && typeof f.toString === 'function') {
|
||||||
|
const str = f.toString();
|
||||||
|
if (typeof str === 'string' && str.includes('_detectLoopDelay')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
Object.defineProperty(window, 'location', {
|
disableLaunch(noop);
|
||||||
get: function() { return originalLocation!.get!.call(window); },
|
log.info('anti-devtool: devtools-detector launch hook installed');
|
||||||
set: function(val) {
|
|
||||||
locationBlocked = true;
|
|
||||||
},
|
|
||||||
configurable: true,
|
|
||||||
});
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
log.info(`Script initialized in ${isTopFrame() ? 'top frame' : `iframe (${location.origin})`}`);
|
log.info(`Script initialized in ${isTopFrame() ? 'top frame' : `iframe (${location.origin})`}`);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue