Support catvod proxy

pull/137/head
FongMi 3 years ago
parent dcae9c1ef2
commit 079fe386fa
  1. 4
      app/src/main/java/com/fongmi/android/tv/api/JarLoader.java
  2. 4
      app/src/main/java/com/fongmi/android/tv/api/JsLoader.java
  3. 4
      app/src/main/java/com/fongmi/android/tv/api/PyLoader.java
  4. 4
      drpy/src/main/java/com/hiker/drpy/Proxy.java
  5. 62
      drpy/src/main/java/com/hiker/drpy/Spider.java
  6. 64
      drpy/src/main/java/com/hiker/drpy/bean/Req.java
  7. 46
      drpy/src/main/java/com/hiker/drpy/bean/Res.java
  8. 9
      drpy/src/main/java/com/hiker/drpy/method/Function.java
  9. 66
      drpy/src/main/java/com/hiker/drpy/method/Global.java

@ -131,8 +131,8 @@ public class JarLoader {
public Object[] proxyInvoke(Map<?, ?> params) {
try {
Method method = methods.get(Utils.getMd5(recent));
if (method != null) return (Object[]) method.invoke(null, params);
else return null;
if (method == null) return null;
return (Object[]) method.invoke(null, params);
} catch (Throwable e) {
e.printStackTrace();
return null;

@ -54,8 +54,8 @@ public class JsLoader {
public Object[] proxyInvoke(Map<?, ?> params) {
try {
Spider spider = spiders.get(recent);
if (spider != null) return spider.proxyLocal(params);
else return null;
if (spider == null) return null;
return spider.proxyLocal(params);
} catch (Throwable e) {
e.printStackTrace();
return null;

@ -54,8 +54,8 @@ public class PyLoader {
public Object[] proxyInvoke(Map<?, ?> params) {
try {
Spider spider = spiders.get(recent);
if (spider != null) return spider.proxyLocal(params);
else return null;
if (spider == null) return null;
return spider.proxyLocal(params);
} catch (Throwable e) {
e.printStackTrace();
return null;

@ -10,14 +10,14 @@ public class Proxy {
if (port > 0) return;
int port = 9978;
while (port < 9999) {
boolean ok = string().equals("ok");
boolean ok = string(port).equals("ok");
if (ok) Proxy.port = port;
if (ok) break;
port++;
}
}
private static String string() {
private static String string(int port) {
try {
return OkHttp.newCall("http://127.0.0.1:" + port + "/proxy?do=port").execute().body().string();
} catch (Exception e) {

@ -1,8 +1,10 @@
package com.hiker.drpy;
import android.content.Context;
import android.util.Base64;
import com.github.catvod.utils.Json;
import com.hiker.drpy.bean.Res;
import com.hiker.drpy.method.Function;
import com.hiker.drpy.method.Global;
import com.hiker.drpy.method.Local;
@ -16,6 +18,7 @@ import org.json.JSONArray;
import java.io.ByteArrayInputStream;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -54,7 +57,7 @@ public class Spider extends com.github.catvod.crawler.Spider {
return executor.submit(callable);
}
private Object call(String func, Object... args) throws Exception {
private Object[] call(String func, Object... args) throws Exception {
return submit(Function.call(jsObject, func, args)).get();
}
@ -65,58 +68,53 @@ public class Spider extends com.github.catvod.crawler.Spider {
@Override
public String homeContent(boolean filter) throws Exception {
return (String) call("home", filter);
return (String) call("home", filter)[0];
}
@Override
public String homeVideoContent() throws Exception {
return (String) call("homeVod");
return (String) call("homeVod")[0];
}
@Override
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
JSObject obj = submit(() -> convert(extend)).get();
return (String) call("category", tid, pg, filter, obj);
return (String) call("category", tid, pg, filter, obj)[0];
}
@Override
public String detailContent(List<String> ids) throws Exception {
return (String) call("detail", ids.get(0));
return (String) call("detail", ids.get(0))[0];
}
@Override
public String searchContent(String key, boolean quick) throws Exception {
return (String) call("search", key, quick);
return (String) call("search", key, quick)[0];
}
@Override
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
JSArray array = submit(() -> convert(vipFlags)).get();
return (String) call("play", flag, id, array);
return (String) call("play", flag, id, array)[0];
}
@Override
public boolean manualVideoCheck() throws Exception {
return (Boolean) call("sniffer");
return (Boolean) call("sniffer")[0];
}
@Override
public boolean isVideoFormat(String url) throws Exception {
return (Boolean) call("isVideo", url);
return (Boolean) call("isVideo", url)[0];
}
@Override
public Object[] proxyLocal(Map<?, ?> params) throws Exception {
return submit(() -> {
JSObject obj = ctx.createNewJSObject();
for (Object key : params.keySet()) obj.setProperty((String) key, (String) params.get(key));
JSONArray array = new JSONArray(((JSArray) jsObject.getJSFunction("proxy").call(obj)).stringify());
Object[] result = new Object[3];
result[0] = array.opt(0);
result[1] = array.opt(1);
result[2] = getStream(array.opt(2));
return result;
}).get();
if ("catvod".equals(params.get("from"))) {
return proxy2(params);
} else {
return submit(() -> proxy1(params)).get();
}
}
@Override
@ -218,6 +216,31 @@ public class Spider extends com.github.catvod.crawler.Spider {
return array;
}
private Object[] proxy1(Map<?, ?> params) throws Exception {
JSObject obj = ctx.createNewJSObject();
for (Object key : params.keySet()) obj.setProperty((String) key, (String) params.get(key));
JSONArray array = new JSONArray(((JSArray) jsObject.getJSFunction("proxy").call(obj)).stringify());
Object[] result = new Object[3];
result[0] = array.opt(0);
result[1] = array.opt(1);
result[2] = getStream(array.opt(2));
return result;
}
private Object[] proxy2(Map<?, ?> params) throws Exception {
String url = (String) params.get("url");
String header = (String) params.get("header");
JSArray array = submit(() -> convert(Arrays.asList(url.split("/")))).get();
Object object = submit(() -> ctx.parse(header)).get();
String json = (String) call("proxy", array, object)[0];
Res res = Res.objectFrom(json);
Object[] result = new Object[3];
result[0] = 200;
result[1] = "application/octet-stream";
result[2] = new ByteArrayInputStream(Base64.decode(res.getContent(), Base64.DEFAULT));
return result;
}
private ByteArrayInputStream getStream(Object o) {
if (o instanceof JSONArray) {
JSONArray a = (JSONArray) o;
@ -229,3 +252,4 @@ public class Spider extends com.github.catvod.crawler.Spider {
}
}
}

@ -0,0 +1,64 @@
package com.hiker.drpy.bean;
import android.text.TextUtils;
import com.github.catvod.utils.Json;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.annotations.SerializedName;
import java.util.Map;
public class Req {
@SerializedName("buffer")
private Integer buffer;
@SerializedName("redirect")
private Integer redirect;
@SerializedName("timeout")
private Integer timeout;
@SerializedName("method")
private String method;
@SerializedName("body")
private String body;
@SerializedName("data")
private String data;
@SerializedName("headers")
private JsonElement headers;
public static Req objectFrom(String json) {
return new Gson().fromJson(json, Req.class);
}
public int getBuffer() {
return buffer == null ? 0 : buffer;
}
public Integer getRedirect() {
return redirect == null ? 1 : redirect;
}
public Integer getTimeout() {
return timeout == null ? 10000 : timeout;
}
public String getMethod() {
return TextUtils.isEmpty(method) ? "get" : method;
}
public String getBody() {
return TextUtils.isEmpty(body) ? "" : body;
}
public String getData() {
return TextUtils.isEmpty(data) ? "" : data;
}
private JsonElement getHeaders() {
return headers;
}
public Map<String, String> getHeader() {
return Json.toMap(getHeaders());
}
}

@ -0,0 +1,46 @@
package com.hiker.drpy.bean;
import android.text.TextUtils;
import com.github.catvod.utils.Json;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.annotations.SerializedName;
import java.util.Map;
public class Res {
@SerializedName("code")
private Integer code;
@SerializedName("buffer")
private Integer buffer;
@SerializedName("content")
private String content;
@SerializedName("headers")
private JsonElement headers;
public static Res objectFrom(String json) {
return new Gson().fromJson(json, Res.class);
}
public int getCode() {
return code == null ? 200 : code;
}
public int getBuffer() {
return buffer == null ? 0 : buffer;
}
public String getContent() {
return TextUtils.isEmpty(content) ? "" : content;
}
private JsonElement getHeaders() {
return headers;
}
public Map<String, String> getHeader() {
return Json.toMap(getHeaders());
}
}

@ -6,7 +6,7 @@ import com.whl.quickjs.wrapper.JSObject;
import java.util.concurrent.Callable;
public class Function implements Callable<Object> {
public class Function implements Callable<Object[]> {
private final JSObject jsObject;
private final Object[] args;
@ -24,10 +24,10 @@ public class Function implements Callable<Object> {
}
@Override
public Object call() throws Exception {
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);
return new Object[]{async ? async(func) : func.call(args)};
}
private Object async(JSFunction func) {
@ -40,7 +40,8 @@ public class Function implements Callable<Object> {
private final JSCallFunction jsCallFunction = new JSCallFunction() {
@Override
public Object call(Object... args) {
return result = args[0];
result = args[0];
return null;
}
};
}

@ -6,20 +6,19 @@ import android.util.Base64;
import androidx.annotation.Keep;
import com.github.catvod.net.OkHttp;
import com.hiker.drpy.Proxy;
import com.google.gson.Gson;
import com.hiker.drpy.Parser;
import com.hiker.drpy.Proxy;
import com.hiker.drpy.bean.Req;
import com.whl.quickjs.wrapper.JSArray;
import com.whl.quickjs.wrapper.JSFunction;
import com.whl.quickjs.wrapper.JSMethod;
import com.whl.quickjs.wrapper.JSObject;
import com.whl.quickjs.wrapper.QuickJSContext;
import org.json.JSONObject;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.net.URLEncoder;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
@ -68,13 +67,19 @@ public class Global {
@Keep
@JSMethod
public String getProxy(boolean local) {
public String getProxy(Boolean local) {
return Proxy.getUrl() + "?do=js";
}
@Keep
@JSMethod
public Object setTimeout(JSFunction func, int delay) {
public String js2Proxy(Boolean dynamic, Integer siteType, String siteKey, String url, JSObject headers) {
return getProxy(true) + "&from=catvod" + "&header=" + URLEncoder.encode(ctx.stringify(headers)) + "&url=" + URLEncoder.encode(url);
}
@Keep
@JSMethod
public Object setTimeout(JSFunction func, Integer delay) {
func.hold();
schedule(func, delay);
return null;
@ -86,12 +91,12 @@ public class Global {
try {
JSObject jsObject = ctx.createNewJSObject();
JSObject jsHeader = ctx.createNewJSObject();
JSONObject obj = new JSONObject(ctx.stringify(object));
Headers headers = getHeader(obj.optJSONObject("headers"));
Response response = call(url, obj, headers).execute();
Req req = Req.objectFrom(ctx.stringify(object));
Headers headers = Headers.of(req.getHeader());
Response response = call(url, req, headers).execute();
for (String name : response.headers().names()) jsHeader.setProperty(name, response.header(name));
jsObject.setProperty("headers", jsHeader);
setContent(jsObject, headers, obj.optInt("buffer"), response.body().bytes());
setContent(jsObject, headers, req.getBuffer(), response.body().bytes());
return jsObject;
} catch (Throwable e) {
JSObject jsObject = ctx.createNewJSObject();
@ -156,48 +161,35 @@ public class Global {
timer.schedule(new TimerTask() {
@Override
public void run() {
if (!executor.isShutdown()) executor.submit(() -> { func.call(); });
if (!executor.isShutdown()) executor.submit(() -> {
func.call();
});
}
}, delay);
}
private Call call(String url, JSONObject object, Headers headers) {
int redirect = object.optInt("redirect", 1);
int timeout = object.optInt("timeout", 10000);
OkHttpClient client = redirect == 1 ? OkHttp.client() : OkHttp.noRedirect();
client = client.newBuilder().connectTimeout(timeout, TimeUnit.MILLISECONDS).readTimeout(timeout, TimeUnit.MILLISECONDS).writeTimeout(timeout, TimeUnit.MILLISECONDS).build();
return client.newCall(getRequest(url, object, headers));
private Call call(String url, Req req, Headers headers) {
OkHttpClient client = req.getRedirect() == 1 ? OkHttp.client() : OkHttp.noRedirect();
client = client.newBuilder().connectTimeout(req.getTimeout(), TimeUnit.MILLISECONDS).readTimeout(req.getTimeout(), TimeUnit.MILLISECONDS).writeTimeout(req.getTimeout(), TimeUnit.MILLISECONDS).build();
return client.newCall(getRequest(url, req, headers));
}
private Request getRequest(String url, JSONObject object, Headers headers) {
String method = object.optString("method", "get");
if (method.equalsIgnoreCase("post")) {
return new Request.Builder().url(url).headers(headers).post(getPostBody(object, headers.get("Content-Type"))).build();
} else if (method.equalsIgnoreCase("header")) {
private Request getRequest(String url, Req req, Headers headers) {
if (req.getMethod().equalsIgnoreCase("post")) {
return new Request.Builder().url(url).headers(headers).post(getPostBody(req, headers.get("Content-Type"))).build();
} else if (req.getMethod().equalsIgnoreCase("header")) {
return new Request.Builder().url(url).headers(headers).head().build();
} else {
return new Request.Builder().url(url).headers(headers).get().build();
}
}
private RequestBody getPostBody(JSONObject object, String contentType) {
String body = object.optString("body").trim();
String data = object.optString("data").trim();
if (data.length() > 0) return RequestBody.create(data, MediaType.get("application/json"));
if (body.length() > 0 && contentType != null) return RequestBody.create(body, MediaType.get(contentType));
private RequestBody getPostBody(Req req, String contentType) {
if (req.getData().length() > 0) return RequestBody.create(req.getData(), MediaType.get("application/json"));
if (req.getBody().length() > 0 && contentType != null) return RequestBody.create(req.getBody(), MediaType.get(contentType));
return RequestBody.create("", null);
}
private Headers getHeader(JSONObject object) {
Headers.Builder builder = new Headers.Builder();
if (object == null) return builder.build();
for (Iterator<String> iterator = object.keys(); iterator.hasNext(); ) {
String key = iterator.next();
builder.add(key, object.optString(key));
}
return builder.build();
}
private String getCharset(Headers headers) {
String contentType = headers.get("Content-Type");
if (TextUtils.isEmpty(contentType)) return "UTF-8";

Loading…
Cancel
Save