Support catvod js without garble

pull/137/head
FongMi 3 years ago
parent 8e0d5ad0d4
commit e3b25722c0
  1. 43
      drpy/src/main/java/com/hiker/drpy/Spider.java
  2. 46
      drpy/src/main/java/com/hiker/drpy/method/Function.java

@ -3,6 +3,7 @@ package com.hiker.drpy;
import android.content.Context;
import com.github.catvod.utils.Json;
import com.hiker.drpy.method.Function;
import com.hiker.drpy.method.Global;
import com.hiker.drpy.method.Local;
import com.whl.quickjs.android.QuickJSLoader;
@ -23,6 +24,8 @@ import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import dalvik.system.DexClassLoader;
@ -35,11 +38,12 @@ public class Spider extends com.github.catvod.crawler.Spider {
private final String key;
private final String api;
public Spider(String api, DexClassLoader dex) {
public Spider(String api, DexClassLoader dex) throws Exception {
this.key = "__" + UUID.randomUUID().toString().replace("-", "") + "__";
this.executor = Executors.newSingleThreadExecutor();
this.api = api;
this.dex = dex;
initializeJS();
}
private void submit(Runnable runnable) {
@ -51,13 +55,12 @@ public class Spider extends com.github.catvod.crawler.Spider {
}
private Object call(String func, Object... args) throws Exception {
return submit(() -> jsObject.getJSFunction(func).call(args)).get();
return submit(Function.call(jsObject, func, args)).get();
}
@Override
public void init(Context context, String extend) throws Exception {
super.init(context, extend);
submit(() -> initJS(extend));
call("init", Json.valid(extend) ? ctx.parse(extend) : extend);
}
@Override
@ -124,13 +127,14 @@ public class Spider extends com.github.catvod.crawler.Spider {
});
}
private void initJS(String extend) {
if (ctx == null) createCtx();
if (dex != null) createDex();
String content = getContent();
ctx.evaluateModule(content, api);
jsObject = (JSObject) ctx.getProperty(ctx.getGlobalObject(), key);
jsObject.getJSFunction("init").call(Json.valid(extend) ? ctx.parse(extend) : extend);
private void initializeJS() throws Exception {
submit(() -> {
if (ctx == null) createCtx();
if (dex != null) createDex();
ctx.evaluateModule(getContent(), api);
jsObject = (JSObject) ctx.getProperty(ctx.getGlobalObject(), key);
return null;
}).get();
}
private void createCtx() {
@ -184,9 +188,20 @@ public class Spider extends com.github.catvod.crawler.Spider {
}
private String getContent() {
return Module.get().load(api)
.replace("__JS_SPIDER__", "globalThis." + key)
.replaceAll("export default.*?[{]", "globalThis." + key + " = {");
String content = Module.get().load(api);
if (content.contains("__jsEvalReturn")) {
return catvod(content);
} else if (content.contains("__JS_SPIDER__")) {
return content.replace("__JS_SPIDER__", "globalThis." + key);
} else {
return content.replaceAll("export default.*?[{]", "globalThis." + key + " = {");
}
}
private String catvod(String content) {
String[] split = content.split("export\\s+function\\s+__jsEvalReturn.*?[{]");
Matcher matcher = Pattern.compile("\\s?return\\s?([\\s+\\S]*)\\s?\\}").matcher(split[1]);
return matcher.find() ? split[0].concat("globalThis." + key + " = ").concat(matcher.group(1)) : content;
}
private JSObject convert(HashMap<String, String> map) {

@ -0,0 +1,46 @@
package com.hiker.drpy.method;
import com.whl.quickjs.wrapper.JSCallFunction;
import com.whl.quickjs.wrapper.JSFunction;
import com.whl.quickjs.wrapper.JSObject;
import java.util.concurrent.Callable;
public class Function implements Callable<Object> {
private final JSObject jsObject;
private final Object[] args;
private final String name;
private Object result;
public static Function call(JSObject jsObject, String name, Object[] args) {
return new Function(jsObject, name, args);
}
private Function(JSObject jsObject, String name, Object[] args) {
this.jsObject = jsObject;
this.name = name;
this.args = args;
}
@Override
public Object call() throws Exception {
JSFunction func = jsObject.getJSFunction(name);
boolean async = func.getJSFunction("toString").call().toString().startsWith("async");
return async ? async(func) : func.call(args);
}
private Object async(JSFunction func) {
JSObject promise = (JSObject) func.call(args);
JSFunction then = promise.getJSFunction("then");
then.call(jsCallFunction);
return result;
}
private final JSCallFunction jsCallFunction = new JSCallFunction() {
@Override
public Object call(Object... args) {
return result = args[0];
}
};
}
Loading…
Cancel
Save