diff --git a/src/file.ts b/src/file.ts index 37d5729..fec937c 100644 --- a/src/file.ts +++ b/src/file.ts @@ -1,11 +1,10 @@ /* eslint-disable no-extend-native */ import scoreinfo from './scoreinfo' -import { webpackHook, webpackGlobalOverride, ALL } from './webpack-hook' +import { webpackHook, webpackGlobalOverride } from './webpack-hook' -const FILE_URL_MODULE_ID = 'iNJA' -const ARG_NUMBER = 4 -const MAGIC_ARG_INDEX = 3 +const AUTH_MODULE_ID = 'UeBv' +const MAGIC_ARG_INDEX = 1 type FileType = 'img' | 'mp3' | 'midi' @@ -14,35 +13,23 @@ type FileType = 'img' | 'mp3' | 'midi' */ let magic: Promise | string = new Promise((resolve) => { // todo: hook module by what it does, not what it is called - webpackGlobalOverride(ALL, (_, r, t) => { // override - const fn = r.a - if (typeof fn === 'function' && fn.length === ARG_NUMBER) { - t.d(r, 'a', () => { - return (...args) => { - if (magic instanceof Promise) { - if (args.every(a => typeof a === 'number' || typeof a === 'string')) { - magic = args[MAGIC_ARG_INDEX] - resolve(magic) - } - } - return fn(...args) as string - } - }) + webpackGlobalOverride(AUTH_MODULE_ID, (n, r, t) => { // override + const fn = n.exports + n.exports = (...args) => { + if (magic instanceof Promise) { + magic = args[MAGIC_ARG_INDEX] + resolve(magic) + } + return fn(...args) as string } }) }) -export const getFileUrl = async (type: FileType, index = 0): Promise => { - const fileUrlModule = webpackHook(FILE_URL_MODULE_ID, { - '6Ulw' (_, r, t) { // override - t.d(r, 'a', () => { - return type - }) - }, - }) - - const fn: (_, id: number, index: number, cb: (url: string) => any, magic: string) => string = fileUrlModule.a +const getApiUrl = (type: FileType, index: number): string => { + return `/api/jmuse?id=${scoreinfo.id}&type=${type}&index=${index}` +} +const getApiAuth = async (type: FileType, index: number): Promise => { if (magic instanceof Promise) { // force to retrieve the MAGIC const el = document.querySelectorAll('.SD7H- > button')[3] as HTMLButtonElement @@ -50,7 +37,23 @@ export const getFileUrl = async (type: FileType, index = 0): Promise => magic = await magic } - return new Promise((resolve) => { - return fn(undefined, scoreinfo.id, index, resolve, magic as string) - }) + const str = String(scoreinfo.id) + type + String(index) + + const fn: (str: string, magic: string) => string = webpackHook(AUTH_MODULE_ID) + + return fn(str, magic) +} + +export const getFileUrl = async (type: FileType, index = 0): Promise => { + const url = getApiUrl(type, index) + const auth = await getApiAuth(type, index) + + const r = await fetch(url, { + headers: { + Authorization: auth, + }, + }) + + const { info } = await r.json() + return info.url as string } diff --git a/src/webpack-hook.ts b/src/webpack-hook.ts index aef07b4..93a7137 100644 --- a/src/webpack-hook.ts +++ b/src/webpack-hook.ts @@ -3,7 +3,7 @@ import { hookNative } from './anti-detection' -const CHUNK_PUSH_FN = 'function a(a){' +const CHUNK_PUSH_FN = /^function [^r]\(\w\){/ interface Module { (module, exports, __webpack_require__): void; @@ -88,7 +88,7 @@ export const webpackGlobalOverride = (() => { get () { return jsonp }, set (v: WebpackJson) { jsonp = v - if (!hooked && v.push.toString().includes(CHUNK_PUSH_FN)) { + if (!hooked && v.push.toString().match(CHUNK_PUSH_FN)) { hooked = true hookNative(v, 'push', (_fn) => { return function (pack) {