Merge branch 'dev' into release

pull/137/head
FongMi 3 years ago
commit 5bc5e1843e
  1. 33
      app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java
  2. 87
      app/src/main/java/com/fongmi/android/tv/api/Decoder.java
  3. 2
      app/src/main/java/com/fongmi/android/tv/api/JarLoader.java
  4. 5
      app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java
  5. 11
      app/src/main/java/com/fongmi/android/tv/utils/Json.java
  6. 2
      app/src/main/java/com/fongmi/android/tv/utils/Updater.java
  7. 6
      app/src/main/java/com/fongmi/android/tv/utils/Utils.java

@ -10,7 +10,6 @@ import com.fongmi.android.tv.bean.Live;
import com.fongmi.android.tv.bean.Parse;
import com.fongmi.android.tv.bean.Site;
import com.fongmi.android.tv.net.Callback;
import com.fongmi.android.tv.net.OKHttp;
import com.fongmi.android.tv.utils.FileUtil;
import com.fongmi.android.tv.utils.Json;
import com.fongmi.android.tv.utils.Prefers;
@ -20,11 +19,9 @@ import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader;
import org.json.JSONObject;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@ -86,38 +83,26 @@ public class ApiConfig {
public void loadConfig(boolean cache, Callback callback) {
new Thread(() -> {
String url = Prefers.getUrl();
if (cache) getCacheConfig(url, callback);
else if (url.startsWith("http")) getWebConfig(url, callback);
else if (url.startsWith("file")) getFileConfig(url, callback);
else handler.post(() -> callback.error(0));
if (cache) loadCache(Prefers.getUrl(), callback);
else loadConfig(Prefers.getUrl(), callback);
}).start();
}
private void getFileConfig(String url, Callback callback) {
try {
parseConfig(new Gson().fromJson(new JsonReader(new FileReader(FileUtil.getLocal(url))), JsonObject.class), callback);
} catch (Exception e) {
e.printStackTrace();
getCacheConfig(url, callback);
}
private void loadCache(String url, Callback callback) {
String json = Config.find(url).getJson();
if (!TextUtils.isEmpty(json)) parseConfig(JsonParser.parseString(json).getAsJsonObject(), callback);
else handler.post(() -> callback.error(R.string.error_config_get));
}
private void getWebConfig(String url, Callback callback) {
private void loadConfig(String url, Callback callback) {
try {
parseConfig(new Gson().fromJson(OKHttp.newCall(url).execute().body().string(), JsonObject.class), callback);
parseConfig(new Gson().fromJson(Decoder.getJson(url), JsonObject.class), callback);
} catch (Exception e) {
e.printStackTrace();
getCacheConfig(url, callback);
loadCache(url, callback);
}
}
private void getCacheConfig(String url, Callback callback) {
String json = Config.find(url).getJson();
if (!TextUtils.isEmpty(json)) parseConfig(JsonParser.parseString(json).getAsJsonObject(), callback);
else handler.post(() -> callback.error(R.string.error_config_get));
}
private void parseConfig(JsonObject object, Callback callback) {
try {
parseJson(object);

@ -0,0 +1,87 @@
package com.fongmi.android.tv.api;
import android.util.Base64;
import com.fongmi.android.tv.net.OKHttp;
import com.fongmi.android.tv.utils.FileUtil;
import com.fongmi.android.tv.utils.Json;
import com.google.common.io.BaseEncoding;
import java.nio.charset.StandardCharsets;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class Decoder {
public static String getJson(String url) throws Exception {
String key = url.contains(";") ? url.split(";")[2] : "";
url = url.contains(";") ? url.split(";")[0] : url;
String data = getData(url);
if (Json.valid(data)) return data;
if (data.contains("**")) data = base64(data);
if (data.startsWith("2423")) data = cbc(data);
if (key.length() > 0) data = ecb(data, key);
return data;
}
public static String getExt(String ext) {
try {
return base64(OKHttp.newCall(ext.substring(4)).execute().body().string());
} catch (Exception ignored) {
return "";
}
}
public static void getSpider(String jar) {
try {
String data = OKHttp.newCall(jar.substring(4)).execute().body().string();
data = data.substring(data.indexOf("**") + 2);
FileUtil.write(FileUtil.getJar(jar), Base64.decode(data, Base64.DEFAULT));
} catch (Exception ignored) {
}
}
private static String getData(String url) throws Exception {
if (url.startsWith("http")) return OKHttp.newCall(url).execute().body().string();
else if (url.startsWith("file")) return FileUtil.read(url);
throw new Exception();
}
private static String ecb(String data, String key) throws Exception {
SecretKeySpec spec = new SecretKeySpec(padEnd(key), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, spec);
return new String(cipher.doFinal(decodeHex(data)), StandardCharsets.UTF_8);
}
private static String cbc(String data) throws Exception {
int indexKey = data.indexOf("2324") + 4;
String key = new String(decodeHex(data.substring(0, indexKey)), StandardCharsets.UTF_8);
key = key.replace("$#", "").replace("#$", "");
int indexIv = data.length() - 26;
String iv = data.substring(indexIv).trim();
iv = new String(decodeHex(iv), StandardCharsets.UTF_8);
SecretKeySpec keySpec = new SecretKeySpec(padEnd(key), "AES");
IvParameterSpec ivSpec = new IvParameterSpec(padEnd(iv));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
data = data.substring(indexKey, indexIv).trim();
byte[] encryptDataBytes = decodeHex(data);
byte[] decryptData = cipher.doFinal(encryptDataBytes);
return new String(decryptData, StandardCharsets.UTF_8);
}
private static String base64(String data) {
return new String(Base64.decode(data.substring(data.indexOf("**") + 2), Base64.DEFAULT));
}
private static byte[] padEnd(String key) {
return (key + "0000000000000000".substring(key.length())).getBytes(StandardCharsets.UTF_8);
}
public static byte[] decodeHex(String s) {
return BaseEncoding.base16().decode(s.toUpperCase());
}
}

@ -65,7 +65,7 @@ public class JarLoader {
public void parseJar(String key, String jar) {
String[] texts = jar.split(";md5;");
String md5 = jar.startsWith("http") && texts.length > 1 ? texts[1].trim() : "";
String md5 = !jar.startsWith("file") && texts.length > 1 ? texts[1].trim() : "";
jar = texts[0];
if (md5.length() > 0 && FileUtil.equals(jar, md5)) {
load(key, FileUtil.getJar(jar));

@ -70,7 +70,7 @@ public class FileUtil {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(getLocal(path))));
StringBuilder sb = new StringBuilder();
String text;
while ((text = br.readLine()) != null) sb.append(text).append("\n");
while ((text = br.readLine()) != null) sb.append(text);
br.close();
return sb.toString();
} catch (Exception e) {
@ -86,9 +86,8 @@ public class FileUtil {
int count;
while ((count = fis.read(byteArray)) != -1) digest.update(byteArray, 0, count);
fis.close();
byte[] bytes = digest.digest();
StringBuilder sb = new StringBuilder();
for (byte b : bytes) sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
for (byte b : digest.digest()) sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
return sb.toString();
} catch (Exception e) {
return "";

@ -4,12 +4,23 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class Json {
public static boolean valid(String text) {
try {
new JSONObject(text);
return true;
} catch (Exception e) {
return false;
}
}
public static String safeString(JsonObject obj, String key, String value) {
if (obj.has(key)) return obj.getAsJsonPrimitive(key).getAsString().trim();
else return value;

@ -22,7 +22,7 @@ import java.util.concurrent.Executors;
public class Updater implements View.OnClickListener {
private static final String URL = "https://github.com/FongMi/TV/raw/main/release/leanback.json";
private static final String URL = "https://raw.githubusercontent.com/FongMi/TV/release/release/leanback.json";
private static final String PROXY = "https://ghproxy.com/";
private final ExecutorService executor;

@ -86,9 +86,9 @@ public class Utils {
public static String getMD5(String src) {
try {
if (TextUtils.isEmpty(src)) return "";
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] messageDigest = md.digest(src.getBytes());
BigInteger no = new BigInteger(1, messageDigest);
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] bytes = digest.digest(src.getBytes());
BigInteger no = new BigInteger(1, bytes);
StringBuilder sb = new StringBuilder(no.toString(16));
while (sb.length() < 32) sb.insert(0, "0");
return sb.toString().toLowerCase();

Loading…
Cancel
Save