From 880c516bbb83d0817a52446f72ed57df10cfe1b8 Mon Sep 17 00:00:00 2001 From: Demo <> Date: Fri, 24 Jun 2022 23:02:38 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E7=BC=93=E5=AD=98=EF=BC=8C=E4=BC=98=E5=8C=96=E5=88=87=E6=8D=A2?= =?UTF-8?q?=E9=A6=96=E9=A1=B5=E7=9A=84=E5=8A=A0=E8=BD=BD=E9=80=9F=E5=BA=A6?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81spider=E7=9A=84md5=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/misc.xml | 2 +- .../com/github/catvod/crawler/JarLoader.java | 11 +- .../com/github/tvbox/osc/api/ApiConfig.java | 143 +++++++++++++----- .../tvbox/osc/ui/activity/HomeActivity.java | 31 +++- .../ui/activity/ProjectionPlayActivity.java | 2 - .../osc/ui/activity/SettingActivity.java | 9 +- .../tvbox/osc/ui/dialog/RemoteDialog.java | 1 - .../java/com/github/tvbox/osc/util/MD5.java | 52 ++++++- .../main/res/layout/fragment_user_layout.xml | 1 + app/src/main/res/values/dimens.xml | 1 + 10 files changed, 192 insertions(+), 61 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 47002838..860da66a 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + diff --git a/app/src/main/java/com/github/catvod/crawler/JarLoader.java b/app/src/main/java/com/github/catvod/crawler/JarLoader.java index 2b25ac1b..a8f5a9fe 100644 --- a/app/src/main/java/com/github/catvod/crawler/JarLoader.java +++ b/app/src/main/java/com/github/catvod/crawler/JarLoader.java @@ -26,7 +26,7 @@ public class JarLoader { * * @param jarData */ - public boolean load(byte[] jarData) { + public boolean load(String cache) { spiders.clear(); proxyFun = null; boolean success = false; @@ -34,11 +34,6 @@ public class JarLoader { File cacheDir = new File(App.getInstance().getCacheDir().getAbsolutePath() + "/catvod_csp"); if (!cacheDir.exists()) cacheDir.mkdirs(); - String cache = App.getInstance().getCacheDir().getAbsolutePath() + "/catvod_csp.jar"; - FileOutputStream fos = new FileOutputStream(cache); - fos.write(jarData); - fos.flush(); - fos.close(); classLoader = new DexClassLoader(cache, cacheDir.getAbsolutePath(), null, App.getInstance().getClassLoader()); // make force wait here, some device async dex load int count = 0; @@ -46,10 +41,10 @@ public class JarLoader { try { Class classInit = classLoader.loadClass("com.github.catvod.spider.Init"); if (classInit != null) { - success = true; Method method = classInit.getMethod("init", Context.class); method.invoke(null, App.getInstance()); System.out.println("自定义爬虫代码加载成功!"); + success = true; try { Class proxy = classLoader.loadClass("com.github.catvod.spider.Proxy"); Method mth = proxy.getMethod("proxy", Map.class); @@ -59,8 +54,6 @@ public class JarLoader { } break; } - - Thread.sleep(200); } catch (Throwable th) { th.printStackTrace(); diff --git a/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java b/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java index d5dfabcf..81bd216f 100644 --- a/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java +++ b/app/src/main/java/com/github/tvbox/osc/api/ApiConfig.java @@ -7,6 +7,7 @@ import android.util.Base64; import com.github.catvod.crawler.JarLoader; import com.github.catvod.crawler.Spider; +import com.github.tvbox.osc.base.App; import com.github.tvbox.osc.bean.IJKCode; import com.github.tvbox.osc.bean.LiveChannel; import com.github.tvbox.osc.bean.ParseBean; @@ -17,6 +18,7 @@ import com.github.tvbox.osc.server.ControlManager; import com.github.tvbox.osc.util.AdBlocker; import com.github.tvbox.osc.util.DefaultConfig; import com.github.tvbox.osc.util.HawkConfig; +import com.github.tvbox.osc.util.MD5; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -27,6 +29,11 @@ import com.orhanobut.hawk.Hawk; import org.json.JSONObject; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStreamReader; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; @@ -71,45 +78,22 @@ public class ApiConfig { return instance; } - public void loadConfig(LoadConfigCallback callback, Activity activity) { - /*boolean isSourceModeLocal = Hawk.get(HawkConfig.SOURCE_MODE_LOCAL, false); - if (isSourceModeLocal) { - loadConfigLocal(callback, activity); - } else { - loadConfigServer(callback, activity); - }*/ - loadConfigServer(callback, activity); - } - - - public void loadJar(String spider, LoadConfigCallback callback) { - OkGo.get(spider).execute(new AbsCallback() { - @Override - public byte[] convertResponse(okhttp3.Response response) { - try { - return response.body().bytes(); - } catch (Throwable th) { - return null; - } - } - - @Override - public void onFinish() { - super.onFinish(); + public void loadConfig(boolean useCache, LoadConfigCallback callback, Activity activity) { + String apiUrl = Hawk.get(HawkConfig.API_URL, ""); + if (apiUrl.isEmpty()) { + callback.error("-1"); + return; + } + File cache = new File(App.getInstance().getFilesDir().getAbsolutePath() + "/" + MD5.encode(apiUrl)); + if (useCache && cache.exists()) { + try { + parseJson(apiUrl, cache); callback.success(); + return; + } catch (Throwable th) { + th.printStackTrace(); } - - @Override - public void onSuccess(Response response) { - if (response != null && response.body() != null) { - jarLoader.load(response.body()); - } - } - }); - } - - private void loadConfigServer(LoadConfigCallback callback, Activity activity) { - String apiUrl = Hawk.get(HawkConfig.API_URL, ""); + } String apiFix = apiUrl; if (apiUrl.startsWith("clan://")) { apiFix = clanToAddress(apiUrl); @@ -119,7 +103,21 @@ public class ApiConfig { @Override public void onSuccess(Response response) { try { + String json = response.body(); parseJson(apiUrl, response.body()); + try { + File cacheDir = cache.getParentFile(); + if (!cacheDir.exists()) + cacheDir.mkdirs(); + if (cache.exists()) + cache.delete(); + FileOutputStream fos = new FileOutputStream(cache); + fos.write(json.getBytes("UTF-8")); + fos.flush(); + fos.close(); + } catch (Throwable th) { + th.printStackTrace(); + } callback.success(); } catch (Throwable th) { th.printStackTrace(); @@ -130,6 +128,15 @@ public class ApiConfig { @Override public void onError(Response response) { super.onError(response); + if (cache.exists()) { + try { + parseJson(apiUrl, cache); + callback.success(); + return; + } catch (Throwable th) { + th.printStackTrace(); + } + } callback.error("拉取配置失败"); } @@ -148,11 +155,71 @@ public class ApiConfig { }); } + + public void loadJar(String spider, LoadConfigCallback callback) { + String[] urls = spider.split(";md5;"); + String jarUrl = urls[0]; + String md5 = urls.length > 1 ? urls[1].trim() : ""; + File cache = new File(App.getInstance().getFilesDir().getAbsolutePath() + "/csp.jar"); + + if (!md5.isEmpty()) { + if (cache.exists() && MD5.getFileMd5(cache).equalsIgnoreCase(md5)) { + if (jarLoader.load(cache.getAbsolutePath())) { + callback.success(); + } else { + callback.error(""); + } + return; + } + } + + OkGo.get(jarUrl).execute(new AbsCallback() { + + @Override + public File convertResponse(okhttp3.Response response) throws Throwable { + File cacheDir = cache.getParentFile(); + if (!cacheDir.exists()) + cacheDir.mkdirs(); + if (cache.exists()) + cache.delete(); + FileOutputStream fos = new FileOutputStream(cache); + fos.write(response.body().bytes()); + fos.flush(); + fos.close(); + return cache; + } + + @Override + public void onSuccess(Response response) { + if (response.body().exists()) { + if (jarLoader.load(response.body().getAbsolutePath())) { + callback.success(); + } else { + callback.error(""); + } + } else { + callback.error(""); + } + } + }); + } + + private void parseJson(String apiUrl, File f) throws Throwable { + System.out.println("从本地缓存加载" + f.getAbsolutePath()); + BufferedReader bReader = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-8")); + StringBuilder sb = new StringBuilder(); + String s = ""; + while ((s = bReader.readLine()) != null) { + sb.append(s + "\n"); + } + bReader.close(); + parseJson(apiUrl, sb.toString()); + } + private void parseJson(String apiUrl, String jsonStr) { JsonObject infoJson = new Gson().fromJson(jsonStr, JsonObject.class); // spider spider = DefaultConfig.safeJsonString(infoJson, "spider", ""); - spider = spider.split(";md5;")[0]; // 远端站点源 for (JsonElement opt : infoJson.get("sites").getAsJsonArray()) { JsonObject obj = (JsonObject) opt; diff --git a/app/src/main/java/com/github/tvbox/osc/ui/activity/HomeActivity.java b/app/src/main/java/com/github/tvbox/osc/ui/activity/HomeActivity.java index fcc3a90e..7202c51e 100644 --- a/app/src/main/java/com/github/tvbox/osc/ui/activity/HomeActivity.java +++ b/app/src/main/java/com/github/tvbox/osc/ui/activity/HomeActivity.java @@ -8,6 +8,8 @@ import android.animation.ObjectAnimator; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; import android.os.Handler; import android.view.KeyEvent; import android.view.View; @@ -93,12 +95,20 @@ public class HomeActivity extends BaseActivity { return R.layout.activity_home; } + boolean useCacheConfig = false; + @Override protected void init() { EventBus.getDefault().register(this); ControlManager.get().startServer(); initView(); initViewModel(); + useCacheConfig = false; + Intent intent = getIntent(); + if (intent != null && intent.getExtras() != null) { + Bundle bundle = intent.getExtras(); + useCacheConfig = bundle.getBoolean("useCache", false); + } initData(); } @@ -237,6 +247,7 @@ public class HomeActivity extends BaseActivity { mHandler.postDelayed(new Runnable() { @Override public void run() { + Toast.makeText(HomeActivity.this, "jar加载成功", Toast.LENGTH_SHORT).show(); initData(); } }, 50); @@ -249,12 +260,19 @@ public class HomeActivity extends BaseActivity { @Override public void error(String msg) { + jarInitOk = true; + mHandler.post(new Runnable() { + @Override + public void run() { + Toast.makeText(HomeActivity.this, "jar加载失败", Toast.LENGTH_SHORT).show(); + } + }); } }); } return; } - ApiConfig.get().loadConfig(new ApiConfig.LoadConfigCallback() { + ApiConfig.get().loadConfig(useCacheConfig, new ApiConfig.LoadConfigCallback() { AlertDialog dialog = null; @Override @@ -283,6 +301,17 @@ public class HomeActivity extends BaseActivity { @Override public void error(String msg) { + if (msg.equalsIgnoreCase("-1")) { + mHandler.post(new Runnable() { + @Override + public void run() { + dataInitOk = true; + jarInitOk = true; + initData(); + } + }); + return; + } mHandler.post(new Runnable() { @Override public void run() { diff --git a/app/src/main/java/com/github/tvbox/osc/ui/activity/ProjectionPlayActivity.java b/app/src/main/java/com/github/tvbox/osc/ui/activity/ProjectionPlayActivity.java index 027b7a5c..4d147869 100644 --- a/app/src/main/java/com/github/tvbox/osc/ui/activity/ProjectionPlayActivity.java +++ b/app/src/main/java/com/github/tvbox/osc/ui/activity/ProjectionPlayActivity.java @@ -16,8 +16,6 @@ import com.github.tvbox.osc.util.HawkConfig; import com.github.tvbox.osc.util.PlayerHelper; import com.orhanobut.hawk.Hawk; -import java.util.Map; - /** * @author pj567 * @date :2021/3/5 diff --git a/app/src/main/java/com/github/tvbox/osc/ui/activity/SettingActivity.java b/app/src/main/java/com/github/tvbox/osc/ui/activity/SettingActivity.java index a1c090eb..14f25822 100644 --- a/app/src/main/java/com/github/tvbox/osc/ui/activity/SettingActivity.java +++ b/app/src/main/java/com/github/tvbox/osc/ui/activity/SettingActivity.java @@ -1,6 +1,7 @@ package com.github.tvbox.osc.ui.activity; import android.graphics.Color; +import android.os.Bundle; import android.os.Handler; import android.view.KeyEvent; import android.view.View; @@ -187,7 +188,13 @@ public class SettingActivity extends BaseActivity { !currentApi.equals(Hawk.get(HawkConfig.API_URL, "")) || !homeSourceSort.equals(newHomeSourceSort)) { AppManager.getInstance().finishAllActivity(); - jumpActivity(HomeActivity.class); + if (currentApi.equals(Hawk.get(HawkConfig.API_URL, ""))) { + Bundle bundle = new Bundle(); + bundle.putBoolean("useCache", true); + jumpActivity(HomeActivity.class, bundle); + } else { + jumpActivity(HomeActivity.class); + } } else { super.onBackPressed(); } diff --git a/app/src/main/java/com/github/tvbox/osc/ui/dialog/RemoteDialog.java b/app/src/main/java/com/github/tvbox/osc/ui/dialog/RemoteDialog.java index e2366a03..e983abc6 100644 --- a/app/src/main/java/com/github/tvbox/osc/ui/dialog/RemoteDialog.java +++ b/app/src/main/java/com/github/tvbox/osc/ui/dialog/RemoteDialog.java @@ -11,7 +11,6 @@ import androidx.annotation.IdRes; import com.github.tvbox.osc.R; import com.github.tvbox.osc.server.ControlManager; -import com.github.tvbox.osc.server.RemoteServer; import com.github.tvbox.osc.ui.tv.QRCodeGen; /** diff --git a/app/src/main/java/com/github/tvbox/osc/util/MD5.java b/app/src/main/java/com/github/tvbox/osc/util/MD5.java index f909c505..2e23c06b 100644 --- a/app/src/main/java/com/github/tvbox/osc/util/MD5.java +++ b/app/src/main/java/com/github/tvbox/osc/util/MD5.java @@ -4,6 +4,9 @@ import android.text.TextUtils; import android.util.Base64; import android.util.Log; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -31,7 +34,7 @@ public class MD5 { try { MD5.sDigest = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { - Log.e("获取MD5信息摘要失败" , e.getMessage()); + Log.e("获取MD5信息摘要失败", e.getMessage()); } } @@ -49,10 +52,13 @@ public class MD5 { * @return md5值 */ public static String encode(String res) { + byte[] strTemp = res.getBytes(); + return encode(strTemp); + } + private static String encode(byte[] bytes) { try { - byte[] strTemp = res.getBytes(); - sDigest.update(strTemp); + sDigest.update(bytes); byte[] md = sDigest.digest(); int j = md.length; char str[] = new char[j * 2]; @@ -68,15 +74,45 @@ public class MD5 { } } + public static String getFileMd5(File f) { + StringBuffer sb = new StringBuffer(""); + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] buffer = new byte[4096]; + FileInputStream fis = new FileInputStream(f); + int len = 0; + while ((len = fis.read(buffer)) != -1) { + md.update(buffer, 0, len); + } + fis.close(); + byte b[] = md.digest(); + int d; + for (int i = 0; i < b.length; i++) { + d = b[i]; + if (d < 0) { + d = b[i] & 0xff; + } + if (d < 16) + sb.append("0"); + sb.append(Integer.toHexString(d)); + } + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return sb.toString(); + } + /** * MD5加码 生成32位md5码 */ public static String string2MD5(String inStr) { if (sDigest == null) { - Log.e("MD5","MD5信息摘要初始化失败"); + Log.e("MD5", "MD5信息摘要初始化失败"); return null; } else if (TextUtils.isEmpty(inStr)) { - Log.e("MD5","参数strSource不能为空"); + Log.e("MD5", "参数strSource不能为空"); return null; } char[] charArray = inStr.toCharArray(); @@ -104,10 +140,10 @@ public class MD5 { */ public static String encrypt(final String strSource) { if (sDigest == null) { - Log.e("MD5","MD5信息摘要初始化失败"); + Log.e("MD5", "MD5信息摘要初始化失败"); return null; } else if (TextUtils.isEmpty(strSource)) { - Log.e("MD5","参数strSource不能为空"); + Log.e("MD5", "参数strSource不能为空"); return null; } try { @@ -117,7 +153,7 @@ public class MD5 { String strEncrypt = new String(encryptBytes, "utf-8"); return strEncrypt.substring(0, strEncrypt.length() - 1); // 截断Base64产生的换行符 } catch (UnsupportedEncodingException e) { - Log.e("MD5","加密模块暂不支持此字符集合" + e); + Log.e("MD5", "加密模块暂不支持此字符集合" + e); } return null; } diff --git a/app/src/main/res/layout/fragment_user_layout.xml b/app/src/main/res/layout/fragment_user_layout.xml index eaeb84d2..0ea5043c 100644 --- a/app/src/main/res/layout/fragment_user_layout.xml +++ b/app/src/main/res/layout/fragment_user_layout.xml @@ -25,6 +25,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" + android:layout_marginTop="@dimen/vs_25_" android:clipChildren="false" android:clipToPadding="false" android:focusable="false" diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 15c7f75a..74a5f90c 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -19,6 +19,7 @@ -4mm -20mm + -25mm -60mm 0mm From a85ee4f5fcda86da26cf5ccf68b7c79d97f4e4af Mon Sep 17 00:00:00 2001 From: Demo <> Date: Fri, 24 Jun 2022 23:15:23 +0800 Subject: [PATCH 2/2] Bug. --- .../java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java b/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java index c452d139..935a3fe5 100644 --- a/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java +++ b/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java @@ -255,6 +255,8 @@ public class LivePlayActivity extends BaseActivity { } private void initList(List list) { + if (list.isEmpty()) + return; LiveChannel lastChannel = null; String lastChannelName = Hawk.get(HawkConfig.LIVE_CHANNEL, ""); channelList.clear();