|
|
|
|
@ -28,12 +28,14 @@ public class JarLoader { |
|
|
|
|
private final ConcurrentHashMap<String, DexClassLoader> loaders; |
|
|
|
|
private final ConcurrentHashMap<String, Method> methods; |
|
|
|
|
private final ConcurrentHashMap<String, Spider> spiders; |
|
|
|
|
private final ConcurrentHashMap<String, Object> locks; |
|
|
|
|
private String recent; |
|
|
|
|
|
|
|
|
|
public JarLoader() { |
|
|
|
|
loaders = new ConcurrentHashMap<>(); |
|
|
|
|
methods = new ConcurrentHashMap<>(); |
|
|
|
|
spiders = new ConcurrentHashMap<>(); |
|
|
|
|
locks = new ConcurrentHashMap<>(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void clear() { |
|
|
|
|
@ -41,6 +43,7 @@ public class JarLoader { |
|
|
|
|
loaders.clear(); |
|
|
|
|
methods.clear(); |
|
|
|
|
spiders.clear(); |
|
|
|
|
locks.clear(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void setRecent(String recent) { |
|
|
|
|
@ -50,18 +53,19 @@ public class JarLoader { |
|
|
|
|
private void load(String key, File file) { |
|
|
|
|
if (!Path.exists(file) || !file.setReadOnly()) return; |
|
|
|
|
if (Thread.interrupted()) return; |
|
|
|
|
loaders.put(key, dex(file)); |
|
|
|
|
invokeInit(key); |
|
|
|
|
putProxy(key); |
|
|
|
|
DexClassLoader loader = dex(file); |
|
|
|
|
invokeInit(loader); |
|
|
|
|
invokeProxy(key, loader); |
|
|
|
|
loaders.put(key, loader); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private DexClassLoader dex(File file) { |
|
|
|
|
return new DexClassLoader(file.getAbsolutePath(), Path.jar().getAbsolutePath(), Path.jar().getAbsolutePath(), App.get().getClassLoader()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void invokeInit(String key) { |
|
|
|
|
private void invokeInit(DexClassLoader loader) { |
|
|
|
|
try { |
|
|
|
|
Class<?> clz = loaders.get(key).loadClass("com.github.catvod.spider.Init"); |
|
|
|
|
Class<?> clz = loader.loadClass("com.github.catvod.spider.Init"); |
|
|
|
|
Method method = clz.getMethod("init", Context.class); |
|
|
|
|
method.invoke(clz, App.get()); |
|
|
|
|
} catch (Throwable e) { |
|
|
|
|
@ -69,9 +73,9 @@ public class JarLoader { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void putProxy(String key) { |
|
|
|
|
private void invokeProxy(String key, DexClassLoader loader) { |
|
|
|
|
try { |
|
|
|
|
Class<?> clz = loaders.get(key).loadClass("com.github.catvod.spider.Proxy"); |
|
|
|
|
Class<?> clz = loader.loadClass("com.github.catvod.spider.Proxy"); |
|
|
|
|
Method method = clz.getMethod("proxy", Map.class); |
|
|
|
|
methods.put(key, method); |
|
|
|
|
} catch (Throwable e) { |
|
|
|
|
@ -79,27 +83,30 @@ public class JarLoader { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public synchronized void parseJar(String key, String jar) { |
|
|
|
|
public void parseJar(String key, String jar) { |
|
|
|
|
if (loaders.containsKey(key)) return; |
|
|
|
|
String[] texts = jar.split(";md5;"); |
|
|
|
|
String md5 = texts.length > 1 ? texts[1].trim() : ""; |
|
|
|
|
if (md5.startsWith("http")) md5 = OkHttp.string(md5).trim(); |
|
|
|
|
jar = texts[0]; |
|
|
|
|
if (!md5.isEmpty() && Util.equals(jar, md5)) { |
|
|
|
|
load(key, Path.jar(jar)); |
|
|
|
|
} else if (jar.startsWith("http")) { |
|
|
|
|
load(key, Download.create(jar, Path.jar(jar)).get()); |
|
|
|
|
} else if (jar.startsWith("file")) { |
|
|
|
|
load(key, Path.local(jar)); |
|
|
|
|
} else if (jar.startsWith("assets")) { |
|
|
|
|
parseJar(key, UrlUtil.convert(jar)); |
|
|
|
|
if (jar.startsWith("assets")) jar = UrlUtil.convert(jar); |
|
|
|
|
Object lock = locks.computeIfAbsent(key, k -> new Object()); |
|
|
|
|
synchronized (lock) { |
|
|
|
|
if (loaders.containsKey(key)) return; |
|
|
|
|
String[] texts = jar.split(";md5;"); |
|
|
|
|
String md5 = texts.length > 1 ? texts[1].trim() : ""; |
|
|
|
|
if (md5.startsWith("http")) md5 = OkHttp.string(md5).trim(); |
|
|
|
|
jar = texts[0]; |
|
|
|
|
if (!md5.isEmpty() && Util.equals(jar, md5)) { |
|
|
|
|
load(key, Path.jar(jar)); |
|
|
|
|
} else if (jar.startsWith("http")) { |
|
|
|
|
load(key, Download.create(jar, Path.jar(jar)).get()); |
|
|
|
|
} else if (jar.startsWith("file")) { |
|
|
|
|
load(key, Path.local(jar)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public DexClassLoader dex(String jar) { |
|
|
|
|
try { |
|
|
|
|
String jaKey = Util.md5(jar); |
|
|
|
|
if (!loaders.containsKey(jaKey)) parseJar(jaKey, jar); |
|
|
|
|
parseJar(jaKey, jar); |
|
|
|
|
return loaders.get(jaKey); |
|
|
|
|
} catch (Throwable e) { |
|
|
|
|
e.printStackTrace(); |
|
|
|
|
@ -112,7 +119,7 @@ public class JarLoader { |
|
|
|
|
String spKey = jaKey + key; |
|
|
|
|
return spiders.computeIfAbsent(spKey, k -> { |
|
|
|
|
try { |
|
|
|
|
if (!loaders.containsKey(jaKey)) parseJar(jaKey, jar); |
|
|
|
|
parseJar(jaKey, jar); |
|
|
|
|
Spider spider = (Spider) loaders.get(jaKey).loadClass("com.github.catvod.spider." + api.split("csp_")[1]).newInstance(); |
|
|
|
|
spider.siteKey = key; |
|
|
|
|
spider.init(App.get(), ext); |
|
|
|
|
|