diff --git a/app/src/main/java/com/github/catvod/bean/mqitv/Config.java b/app/src/main/java/com/github/catvod/bean/mqitv/Config.java new file mode 100644 index 0000000..3debe69 --- /dev/null +++ b/app/src/main/java/com/github/catvod/bean/mqitv/Config.java @@ -0,0 +1,124 @@ +package com.github.catvod.bean.mqitv; + +import android.net.Uri; + +import androidx.annotation.Nullable; + +import com.github.catvod.net.OkHttp; +import com.google.gson.Gson; +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Config { + + @SerializedName("name") + private String name; + @SerializedName("url") + private String url; + + private List users; + private List data; + private Uri uri; + + public static List arrayFrom(String str) { + Type listType = new TypeToken>() {}.getType(); + return new Gson().fromJson(str, listType); + } + + public Config(String url) { + this.url = url; + } + + public String getName() { + return name == null ? "" : name; + } + + public String getUrl() { + return url == null ? "" : url; + } + + public List getUsers() { + return users = users == null ? new ArrayList<>() : users; + } + + public List getData() { + return data = data == null ? Data.objectFrom(OkHttp.string(getApi())).getData() : data; + } + + public Uri getUri() { + return uri = uri == null ? Uri.parse(getUrl()) : uri; + } + + public String getApi() { + return getUrl() + "/api/post?item=itv_traffic"; + } + + public String getPlayUrl(String port, String playing) { + return "http://" + getUri().getHost() + ":" + port + "/" + playing; + } + + public void loadUser() { + Pattern userPattern = Pattern.compile(".*?([0-9a-zA-Z]{11,}).*", Pattern.CASE_INSENSITIVE); + Pattern macPattern = Pattern.compile(".*?(([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}).*", Pattern.CASE_INSENSITIVE); + for (Data item : getData()) { + for (String userIp : item.getStat().getUserIpList()) { + if (getUsers().size() >= 5) continue; + Matcher userMatcher = userPattern.matcher(userIp); + Matcher macMatcher = macPattern.matcher(userIp); + String user = userMatcher.matches() ? userMatcher.group(1) : ""; + String mac = macMatcher.matches() ? macMatcher.group(1) : ""; + if (!user.isEmpty() && !mac.isEmpty()) { + User u = new User(user, mac).getToken(getUrl()); + if (!u.getToken().isEmpty()) getUsers().add(u); + } + } + } + } + + public User getUser() { + if (getUsers().isEmpty()) loadUser(); + return getUsers().isEmpty() ? new User("", "") : getUsers().get(ThreadLocalRandom.current().nextInt(getUsers().size())); + } + + public String getAuth(String id, String token) { + String data = OkHttp.string(getUrl() + "/ualive?cid=" + id + "&token=" + token); + Matcher matcher = Pattern.compile("\"Reason\":\"(.*?)\"", Pattern.CASE_INSENSITIVE).matcher(data); + if (matcher.find()) return matcher.group(1); + return ""; + } + + public String getM3U8(String id, String token, String port) { + String base = "http://" + getUri().getHost() + ":" + port + "/"; + String m3u8 = OkHttp.string(base + id + ".m3u8?token=" + token); + if (m3u8.contains("\"Reason\"")) return ""; + String[] lines = m3u8.split("\\r?\\n"); + StringBuilder sb = new StringBuilder(); + for (String line : lines) { + if (!line.startsWith("#")) line = base + line; + sb.append(line).append("\n"); + } + return sb.toString(); + } + + public void clear() { + this.data.clear(); + this.users.clear(); + this.data = null; + this.users = null; + } + + @Override + public boolean equals(@Nullable Object obj) { + if (this == obj) return true; + if (!(obj instanceof Config)) return false; + Config it = (Config) obj; + return getUrl().equals(it.getUrl()); + } +} diff --git a/app/src/main/java/com/github/catvod/bean/mqitv/User.java b/app/src/main/java/com/github/catvod/bean/mqitv/User.java index 581480a..25a18bd 100644 --- a/app/src/main/java/com/github/catvod/bean/mqitv/User.java +++ b/app/src/main/java/com/github/catvod/bean/mqitv/User.java @@ -29,8 +29,8 @@ public class User { return token == null ? "" : token; } - public User getToken(String host) { - String result = OkHttp.string(String.format(Locale.getDefault(), "%s/HSAndroidLogin.ecgi?ty=json&net_account=%s&mac_address1=%s&_=%d", host, getId(), getMac(), System.currentTimeMillis())); + public User getToken(String url) { + String result = OkHttp.string(String.format(Locale.getDefault(), "%s/HSAndroidLogin.ecgi?ty=json&net_account=%s&mac_address1=%s&_=%d", url, getId(), getMac(), System.currentTimeMillis())); Pattern pattern = Pattern.compile("\"Token\"\\s*:\\s*\"(.*?)\"", Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(result); token = matcher.find() ? matcher.group(1) : ""; diff --git a/app/src/main/java/com/github/catvod/js/Function.java b/app/src/main/java/com/github/catvod/js/Function.java index ffb9e33..1bb2978 100644 --- a/app/src/main/java/com/github/catvod/js/Function.java +++ b/app/src/main/java/com/github/catvod/js/Function.java @@ -1,7 +1,7 @@ package com.github.catvod.js; -import com.github.catvod.js.utils.Parser; import com.github.catvod.js.utils.JSUtil; +import com.github.catvod.js.utils.Parser; import com.whl.quickjs.wrapper.JSArray; import com.whl.quickjs.wrapper.JSMethod; import com.whl.quickjs.wrapper.QuickJSContext; diff --git a/app/src/main/java/com/github/catvod/spider/MQiTV.java b/app/src/main/java/com/github/catvod/spider/MQiTV.java index adeb6cd..7550780 100644 --- a/app/src/main/java/com/github/catvod/spider/MQiTV.java +++ b/app/src/main/java/com/github/catvod/spider/MQiTV.java @@ -1,63 +1,63 @@ package com.github.catvod.spider; import android.content.Context; -import android.net.Uri; +import com.github.catvod.bean.mqitv.Config; import com.github.catvod.bean.mqitv.Data; -import com.github.catvod.bean.mqitv.User; import com.github.catvod.crawler.Spider; -import com.github.catvod.net.OkHttp; import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.ThreadLocalRandom; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public class MQiTV extends Spider { - private static Map> users; - private static String ext; + private static List configs; - private static String getHost() { - if (ext.startsWith("http")) return ext; - else return "http://" + ext; + public static List getConfigs() { + return configs = configs == null ? new ArrayList<>() : configs; } @Override public void init(Context context, String extend) throws Exception { - users = new HashMap<>(); - ext = extend; + configs = Config.arrayFrom(extend); } @Override public String liveContent(String url) { - List data; StringBuilder sb = new StringBuilder(); - loadUser(data = Data.objectFrom(OkHttp.string(getHost() + "/api/post?item=itv_traffic")).getData()); - for (Data item : data) sb.append(item.getName()).append(",").append(getProxyUrl(item)).append("\n"); + for (Config config : getConfigs()) { + sb.append(config.getName()).append(",#genre#").append("\n"); + boolean hasPort = config.getUri().getPort() != -1; + for (Data item : config.getData()) { + String port = hasPort ? item.getPort() : "5003"; + String proxy = "proxy://do=mqitv&id=" + item.getId() + "&ip=" + config.getUrl() + "&playing=" + item.getPlaying() + "&port=" + port + "&type=m3u8"; + sb.append(item.getName()).append(",").append(proxy).append("\n"); + } + } return sb.toString(); } - private String getProxyUrl(Data item) { - boolean fixed = ext.startsWith("http"); - String port = fixed ? item.getPort() : "5003"; - return "proxy://do=mqitv" + "&id=" + item.getId() + "&ip=" + ext + "&playing=" + item.getPlaying() + "&port=" + port + "&type=m3u8"; + private static Config getConfig(String ip) { + Config config = new Config(ip); + int index = getConfigs().indexOf(config); + if (index != -1) return getConfigs().get(index); + else getConfigs().add(config); + return config; } public static Object[] proxy(Map params) { String ip = params.get("ip"); String port = params.get("port"); if (port == null) port = "5003"; - if (ip != null) ext = ip; - String token = getUser().getToken(); + Config config = getConfig(ip); + String token = config.getUser().getToken(); if (token.isEmpty()) { Map header = new HashMap<>(); String playing = params.get("playing"); - header.put("Location", getStaticUrl(port, playing)); + header.put("Location", config.getPlayUrl(port, playing)); Object[] result = new Object[4]; result[0] = 302; result[1] = "text/plain"; @@ -66,66 +66,14 @@ public class MQiTV extends Spider { return result; } else { String id = params.get("id"); - String auth = authChannel(id, token); - if (!"OK".equals(auth)) { - users.get(getHost()).clear(); - return proxy(params); - } + String auth = config.getAuth(id, token); + if (!"OK".equals(auth)) config.clear(); + if (!"OK".equals(auth)) return proxy(params); Object[] result = new Object[3]; result[0] = 200; result[1] = "application/vnd.apple.mpegurl"; - result[2] = new ByteArrayInputStream(getM3u8(id, port, token).getBytes()); + result[2] = new ByteArrayInputStream(config.getM3U8(id, token, port).getBytes()); return result; } } - - private static void loadUser(List data) { - Pattern userPattern = Pattern.compile(".*?([0-9a-zA-Z]{11,}).*", Pattern.CASE_INSENSITIVE); - Pattern macPattern = Pattern.compile(".*?(([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}).*", Pattern.CASE_INSENSITIVE); - if (!users.containsKey(getHost())) users.put(getHost(), new ArrayList<>()); - for (Data item : data) { - for (String userIp : item.getStat().getUserIpList()) { - if (users.get(getHost()).size() >= 5) continue; - Matcher userMatcher = userPattern.matcher(userIp); - Matcher macMatcher = macPattern.matcher(userIp); - String user = userMatcher.matches() ? userMatcher.group(1) : ""; - String mac = macMatcher.matches() ? macMatcher.group(1) : ""; - if (!user.isEmpty() && !mac.isEmpty()) { - User u = new User(user, mac).getToken(getHost()); - if (!u.getToken().isEmpty()) users.get(getHost()).add(u); - } - } - } - } - - private static User getUser() { - if (users == null) users = new HashMap<>(); - if (!users.containsKey(getHost())) users.put(getHost(), new ArrayList<>()); - if (users.get(getHost()).isEmpty()) loadUser(Data.objectFrom(OkHttp.string(getHost() + "/api/post?item=itv_traffic")).getData()); - return users.get(getHost()).isEmpty() ? new User("", "") : users.get(getHost()).get(ThreadLocalRandom.current().nextInt(users.size())); - } - - private static String authChannel(String id, String token) { - String data = OkHttp.string(getHost() + "/ualive?cid=" + id + "&token=" + token); - Matcher matcher = Pattern.compile("\"Reason\":\"(.*?)\"", Pattern.CASE_INSENSITIVE).matcher(data); - if (matcher.find()) return matcher.group(1); - return ""; - } - - private static String getM3u8(String id, String port, String token) { - String base = "http://" + Uri.parse(getHost()).getHost() + ":" + port + "/"; - String m3u8 = OkHttp.string(base + id + ".m3u8?token=" + token); - if (m3u8.contains("\"Reason\"")) return ""; - String[] lines = m3u8.split("\\r?\\n"); - StringBuilder sb = new StringBuilder(); - for (String line : lines) { - if (!line.startsWith("#")) line = base + line; - sb.append(line).append("\n"); - } - return sb.toString(); - } - - private static String getStaticUrl(String port, String playing) { - return "http://" + Uri.parse(getHost()).getHost() + ":" + port + "/" + playing; - } } diff --git a/jar/custom_spider.jar b/jar/custom_spider.jar index dff7424..d73bc71 100644 Binary files a/jar/custom_spider.jar and b/jar/custom_spider.jar differ diff --git a/jar/custom_spider.jar.md5 b/jar/custom_spider.jar.md5 index 59f4188..b3749a5 100644 --- a/jar/custom_spider.jar.md5 +++ b/jar/custom_spider.jar.md5 @@ -1 +1 @@ -1f6ad25d85981dd689b5534170cdcd42 +ff11d5120db402fd29fb05331915079d