mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2026-08-26 11:32:02 +00:00
e853365fe4
Complete the fake jQuery/document sandbox for cookie, location, querySelector and chained APIs, extract ajax params by regex first with JS fallback, and generate GitHub release notes in a single job so matrix OS uploads no longer append What's Changed twice. Bump version to 0.4.3. Co-authored-by: Cursor <cursoragent@cursor.com>
163 lines
5.5 KiB
Java
163 lines
5.5 KiB
Java
package cn.qaiu.util;
|
||
|
||
import org.apache.commons.lang3.StringUtils;
|
||
import org.openjdk.nashorn.api.scripting.ScriptObjectMirror;
|
||
|
||
import javax.script.Invocable;
|
||
import javax.script.ScriptEngine;
|
||
import javax.script.ScriptEngineManager;
|
||
import javax.script.ScriptException;
|
||
|
||
import java.net.URLEncoder;
|
||
import java.nio.charset.StandardCharsets;
|
||
|
||
import static cn.qaiu.util.AESUtils.encrypt;
|
||
|
||
/**
|
||
* 执行Js脚本
|
||
*
|
||
* @author <a href="https://qaiu.top">QAIU</a>
|
||
* Create at 2023/7/29 17:35
|
||
*/
|
||
public class JsExecUtils {
|
||
private static final Invocable inv;
|
||
private static final ScriptEngineManager ENGINE_MANAGER = new ScriptEngineManager();
|
||
|
||
// 初始化脚本引擎
|
||
static {
|
||
ScriptEngine engine = ENGINE_MANAGER.getEngineByName("JavaScript"); // 得到脚本引擎
|
||
|
||
try {
|
||
engine.eval(JsContent.ye123);
|
||
inv = (Invocable) engine;
|
||
} catch (ScriptException e) {
|
||
throw new RuntimeException(e);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 调用js文件
|
||
*/
|
||
public static ScriptObjectMirror executeJs(String functionName, Object... args) throws ScriptException,
|
||
NoSuchMethodException {
|
||
//调用js中的函数
|
||
return (ScriptObjectMirror) inv.invokeFunction(functionName, args);
|
||
}
|
||
|
||
/**
|
||
* 调用执行蓝奏云js文件(每次动态JS代码,无法复用引擎)
|
||
* 注意:使用后清理引擎引用,帮助 GC 回收 Nashorn 引擎内部资源
|
||
*/
|
||
public static ScriptObjectMirror executeDynamicJs(String jsText, String funName) throws ScriptException,
|
||
NoSuchMethodException {
|
||
return executeDynamicJs(jsText, funName, null);
|
||
}
|
||
|
||
/**
|
||
* @param pwd 分享密码,写入伪 DOM(#pwd / getElementById('pwd')),供新版页面取值
|
||
*/
|
||
public static ScriptObjectMirror executeDynamicJs(String jsText, String funName, String pwd) throws ScriptException,
|
||
NoSuchMethodException {
|
||
ScriptEngine engine = ENGINE_MANAGER.getEngineByName("JavaScript");
|
||
try {
|
||
engine.eval(JsContent.lz);
|
||
Invocable inv = (Invocable) engine;
|
||
if (pwd != null) {
|
||
inv.invokeFunction("__lzSetPwd", pwd);
|
||
}
|
||
try {
|
||
engine.eval(jsText);
|
||
if (StringUtils.isNotEmpty(funName)) {
|
||
inv.invokeFunction(funName);
|
||
}
|
||
} catch (ScriptException | NoSuchMethodException | RuntimeException e) {
|
||
ScriptObjectMirror captured = asSignObj(engine.get("signObj"));
|
||
if (captured != null) {
|
||
return captured;
|
||
}
|
||
throw e;
|
||
}
|
||
return asSignObj(engine.get("signObj"));
|
||
} finally {
|
||
clearEngineBindings(engine);
|
||
}
|
||
}
|
||
|
||
private static ScriptObjectMirror asSignObj(Object sign) {
|
||
if (sign instanceof ScriptObjectMirror mirror
|
||
&& (mirror.get("url") != null || mirror.get("data") != null)) {
|
||
return mirror;
|
||
}
|
||
return null;
|
||
}
|
||
|
||
|
||
/**
|
||
* 调用执行js文件(使用缓存的 ScriptEngineManager 创建新引擎实例)
|
||
* 注意:使用后清理引擎引用,帮助 GC 回收 Nashorn 引擎内部资源
|
||
*/
|
||
public static Object executeOtherJs(String jsText, String funName, Object ... args) throws ScriptException,
|
||
NoSuchMethodException {
|
||
ScriptEngine engine = ENGINE_MANAGER.getEngineByName("JavaScript"); // 得到脚本引擎
|
||
try {
|
||
engine.eval(jsText);
|
||
Invocable inv = (Invocable) engine;
|
||
//调用js中的函数
|
||
if (StringUtils.isNotEmpty(funName)) {
|
||
return inv.invokeFunction(funName, args);
|
||
}
|
||
throw new ScriptException("funName is null");
|
||
} finally {
|
||
// 清理引擎持有的引用,帮助 GC 回收
|
||
clearEngineBindings(engine);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 清理 ScriptEngine 的 bindings,帮助 GC 回收 Nashorn 引擎资源
|
||
*/
|
||
private static void clearEngineBindings(ScriptEngine engine) {
|
||
try {
|
||
if (engine != null) {
|
||
// 清理全局 bindings
|
||
var bindings = engine.getBindings(javax.script.ScriptContext.ENGINE_SCOPE);
|
||
if (bindings != null) {
|
||
bindings.clear();
|
||
}
|
||
}
|
||
} catch (Exception ignored) {
|
||
// 清理失败不影响主流程
|
||
}
|
||
}
|
||
|
||
public static String getKwSign(String s, String pwd) {
|
||
try {
|
||
return executeOtherJs(JsContent.kwSignString, "encrypt", s, pwd).toString();
|
||
} catch (ScriptException | NoSuchMethodException e) {
|
||
throw new RuntimeException(e);
|
||
}
|
||
}
|
||
|
||
public static String mgEncData(String data, String key) {
|
||
try {
|
||
return executeOtherJs(JsContent.mgJS, "enc", data, key).toString();
|
||
} catch (ScriptException | NoSuchMethodException e) {
|
||
throw new RuntimeException(e);
|
||
}
|
||
}
|
||
|
||
|
||
// return OM.AES.encrypt('{"copyrightId":"6326951FKBL","type":1,"auditionsFlag":0}',
|
||
// '4ea5c508a6566e76240543f8feb06fd457777be39549c4016436afda65d2330e').toString()
|
||
//
|
||
|
||
public static void main(String[] args) {
|
||
System.out.println(URLEncoder
|
||
.encode(mgEncData("{\"copyrightId\":\"6326951FKBL\",\"type\":1,\"auditionsFlag\":0}", AESUtils.MG_KEY), StandardCharsets.UTF_8));
|
||
|
||
// U2FsdGVkX1/UiZC91ImQvQY7qDBSEbTykAcVoARiquibPCZhWSs3kWQw3j2PNme5wNLqt2oau498ni1hgjGFuxwORnkk6x9rzk/X0arElUo=
|
||
|
||
}
|
||
|
||
}
|