This commit is contained in:
FongMi 2025-01-22 17:54:17 +08:00
parent 58db696fa5
commit 1da43828a8
4 changed files with 37 additions and 369 deletions

View File

@ -9,7 +9,6 @@ import com.github.catvod.bean.Filter;
import com.github.catvod.bean.Result; import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod; import com.github.catvod.bean.Vod;
import com.github.catvod.crawler.Spider; import com.github.catvod.crawler.Spider;
import com.github.catvod.crawler.SpiderDebug;
import com.github.catvod.net.OkHttp; import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.LZString; import com.github.catvod.utils.LZString;
import com.github.catvod.utils.Util; import com.github.catvod.utils.Util;
@ -30,8 +29,10 @@ import java.util.Map;
* 聚合直播 * 聚合直播
*/ */
public class Living extends Spider { public class Living extends Spider {
private String host = "https://lemonlive.deno.dev"; private String host = "https://lemonlive.deno.dev";
private String cookie = ""; private String cookie = "";
@Override @Override
public void init(Context context, String extend) throws Exception { public void init(Context context, String extend) throws Exception {
if (!TextUtils.isEmpty(extend)) { if (!TextUtils.isEmpty(extend)) {
@ -125,14 +126,14 @@ public class Living extends Spider {
if (type.equals(data.optString("id"))) { if (type.equals(data.optString("id"))) {
for (int j = 0; j < data.optJSONArray("list").length(); j++) { for (int j = 0; j < data.optJSONArray("list").length(); j++) {
JSONObject item = data.optJSONArray("list").optJSONObject(j); JSONObject item = data.optJSONArray("list").optJSONObject(j);
vodList.add(new Vod(tid + "_" + item.optString("cid"), item.optString("name"), item.optString("pic"),data.optString("name"), true)); vodList.add(new Vod(tid + "_" + item.optString("cid"), item.optString("name"), item.optString("pic"), data.optString("name"), true));
} }
} }
} }
return Result.string(vodList); return Result.string(vodList);
} else { } else {
String[] split = tid.split("_"); String[] split = tid.split("_");
String url = host + "/api/" + split[0] + "/getCategoryRooms?id=" + split[1] + "&pid=" + (split[0].equals("bilibili") ? "2":"1") + "&page=" + pg; String url = host + "/api/" + split[0] + "/getCategoryRooms?id=" + split[1] + "&pid=" + (split[0].equals("bilibili") ? "2" : "1") + "&page=" + pg;
if (!TextUtils.isEmpty(cookie)) url = url + "&cookie=" + URLDecoder.decode(cookie, "UTF-8"); if (!TextUtils.isEmpty(cookie)) url = url + "&cookie=" + URLDecoder.decode(cookie, "UTF-8");
JSONObject json = request(url); JSONObject json = request(url);
if (!TextUtils.isEmpty(json.optJSONObject("data").optString("cookie"))) { if (!TextUtils.isEmpty(json.optJSONObject("data").optString("cookie"))) {
@ -194,27 +195,19 @@ public class Living extends Spider {
private String getHuyaParam(String name, String code) throws UnsupportedEncodingException { private String getHuyaParam(String name, String code) throws UnsupportedEncodingException {
String N = "1063681129617"; String N = "1063681129617";
long currentTimeMillis = System.currentTimeMillis(); long currentTimeMillis = System.currentTimeMillis();
String i = String.valueOf(currentTimeMillis % 10000000000L * 1000 + (long)(Math.random() * 4294967295L)); String i = String.valueOf(currentTimeMillis % 10000000000L * 1000 + (long) (Math.random() * 4294967295L));
String r = code.split("fs=")[1].split("&")[0]; String r = code.split("fs=")[1].split("&")[0];
String s = Long.toHexString((currentTimeMillis / 1000) | 21600); String s = Long.toHexString((currentTimeMillis / 1000) | 21600);
String f = String.valueOf(currentTimeMillis + Long.parseLong(N)); String f = String.valueOf(currentTimeMillis + Long.parseLong(N));
String fmPart = code.split("fm=")[1].split("&")[0]; String fmPart = code.split("fm=")[1].split("&")[0];
String c = new String(Base64.decode(URLDecoder.decode(fmPart, "UTF-8"), Base64.NO_WRAP)).split("_")[0]; String c = new String(Base64.decode(URLDecoder.decode(fmPart, "UTF-8"), Base64.NO_WRAP)).split("_")[0];
String u = Util.MD5(f + "|tars_mp|102"); String u = Util.MD5(f + "|tars_mp|102");
return String.format("&wsSecret=%s&uuid=%s&wsTime=%s&uid=%s&seqid=%s&fs=%s&ctype=tars_mp&t=102&ver=1&sv=2401310321", return String.format("&wsSecret=%s&uuid=%s&wsTime=%s&uid=%s&seqid=%s&fs=%s&ctype=tars_mp&t=102&ver=1&sv=2401310321", Util.MD5(c + "_" + N + "_" + name + "_" + u + "_" + s), i, s, N, f, r);
Util.MD5(c + "_" + N + "_" + name + "_" + u + "_" + s),
i,
s,
N,
f,
r);
} }
private JSONObject request(String url) throws JSONException { private JSONObject request(String url) throws JSONException {
String str = OkHttp.string(url, Map.of("sec-fetch-site", "same-origin")); String str = OkHttp.string(url, Map.of("sec-fetch-site", "same-origin"));
String result = LZString.decompressFromBase64(str.replaceAll(" ", "")); String result = LZString.decompressFromBase64(str.replaceAll(" ", ""));
//SpiderDebug.log("result==" + result);
return new JSONObject(result); return new JSONObject(result);
} }
} }

View File

@ -9,19 +9,19 @@ package com.github.catvod.utils;
* https://github.com/pieroxy/lz-string * https://github.com/pieroxy/lz-string
*/ */
import android.text.TextUtils;
import java.util.*; import java.util.*;
public class LZString { public class LZString {
private static char[] keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray(); private static final char[] keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();
private static char[] keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$".toCharArray(); private static final Map<char[], Map<Character, Integer>> baseReverseDic = new HashMap<>();
private static Map<char[], Map<Character, Integer>> baseReverseDic = new HashMap<char[], Map<Character, Integer>>();
private static char getBaseValue(char[] alphabet, Character character) { private static char getBaseValue(char[] alphabet, Character character) {
Map<Character, Integer> map = baseReverseDic.get(alphabet); Map<Character, Integer> map = baseReverseDic.get(alphabet);
if (map == null) { if (map == null) {
map = new HashMap<Character, Integer>(); map = new HashMap<>();
baseReverseDic.put(alphabet, map); baseReverseDic.put(alphabet, map);
for (int i = 0; i < alphabet.length; i++) { for (int i = 0; i < alphabet.length; i++) {
map.put(alphabet[i], i); map.put(alphabet[i], i);
@ -30,34 +30,9 @@ public class LZString {
return (char) map.get(character).intValue(); return (char) map.get(character).intValue();
} }
public static String compressToBase64(String input) {
if (input == null)
return "";
String res = LZString._compress(input, 6, new CompressFunctionWrapper() {
@Override
public char doFunc(int a) {
return keyStrBase64[a];
}
});
switch (res.length() % 4) { // To produce valid Base64
default: // When could this happen ?
case 0:
return res;
case 1:
return res + "===";
case 2:
return res + "==";
case 3:
return res + "=";
}
}
public static String decompressFromBase64(final String inputStr) { public static String decompressFromBase64(final String inputStr) {
if (inputStr == null) if (TextUtils.isEmpty(inputStr)) return "";
return ""; return _decompress(inputStr.length(), 32, new DecompressFunctionWrapper() {
if (inputStr.equals(""))
return null;
return LZString._decompress(inputStr.length(), 32, new DecompressFunctionWrapper() {
@Override @Override
public char doFunc(int index) { public char doFunc(int index) {
return getBaseValue(keyStrBase64, inputStr.charAt(index)); return getBaseValue(keyStrBase64, inputStr.charAt(index));
@ -65,286 +40,10 @@ public class LZString {
}); });
} }
public static String compressToUTF16(String input) {
if (input == null)
return "";
return LZString._compress(input, 15, new CompressFunctionWrapper() {
@Override
public char doFunc(int a) {
return fc(a + 32);
}
}) + " ";
}
public static String decompressFromUTF16(final String compressedStr) {
if (compressedStr == null)
return "";
if (compressedStr.isEmpty())
return null;
return LZString._decompress(compressedStr.length(), 16384, new DecompressFunctionWrapper() {
@Override
public char doFunc(int index) {
return (char) (compressedStr.charAt(index) - 32);
}
});
}
//TODO: java has no Uint8Array type, what can we do?
public static String compressToEncodedURIComponent(String input) {
if (input == null)
return "";
return LZString._compress(input, 6, new CompressFunctionWrapper() {
@Override
public char doFunc(int a) {
return keyStrUriSafe[a];
}
});
}
public static String decompressFromEncodedURIComponent(String inputStr) {
if (inputStr == null) return "";
if (inputStr.isEmpty()) return null;
final String urlEncodedInputStr = inputStr.replace(' ', '+');
return LZString._decompress(urlEncodedInputStr.length(), 32, new DecompressFunctionWrapper() {
@Override
public char doFunc(int index) {
return getBaseValue(keyStrUriSafe, urlEncodedInputStr.charAt(index));
}
});
}
private static abstract class CompressFunctionWrapper {
public abstract char doFunc(int i);
}
public static String compress(String uncompressed) {
return LZString._compress(uncompressed, 16, new CompressFunctionWrapper() {
@Override
public char doFunc(int a) {
return fc(a);
}
});
}
private static String _compress(String uncompressedStr, int bitsPerChar, CompressFunctionWrapper getCharFromInt) {
if (uncompressedStr == null) return "";
int i, value;
Map<String, Integer> context_dictionary = new HashMap<String, Integer>();
Set<String> context_dictionaryToCreate = new HashSet<String>();
String context_c = "";
String context_wc = "";
String context_w = "";
int context_enlargeIn = 2; // Compensate for the first entry which should not count
int context_dictSize = 3;
int context_numBits = 2;
StringBuilder context_data = new StringBuilder(uncompressedStr.length() / 3);
int context_data_val = 0;
int context_data_position = 0;
int ii;
for (ii = 0; ii < uncompressedStr.length(); ii += 1) {
context_c = String.valueOf(uncompressedStr.charAt(ii));
if (!context_dictionary.containsKey(context_c)) {
context_dictionary.put(context_c, context_dictSize++);
context_dictionaryToCreate.add(context_c);
}
context_wc = context_w + context_c;
if (context_dictionary.containsKey(context_wc)) {
context_w = context_wc;
} else {
if (context_dictionaryToCreate.contains(context_w)) {
if (context_w.charAt(0) < 256) {
for (i = 0; i < context_numBits; i++) {
context_data_val = (context_data_val << 1);
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.append(getCharFromInt.doFunc(context_data_val));
context_data_val = 0;
} else {
context_data_position++;
}
}
value = context_w.charAt(0);
for (i = 0; i < 8; i++) {
context_data_val = (context_data_val << 1) | (value & 1);
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.append(getCharFromInt.doFunc(context_data_val));
context_data_val = 0;
} else {
context_data_position++;
}
value = value >> 1;
}
} else {
value = 1;
for (i = 0; i < context_numBits; i++) {
context_data_val = (context_data_val << 1) | value;
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.append(getCharFromInt.doFunc(context_data_val));
context_data_val = 0;
} else {
context_data_position++;
}
value = 0;
}
value = context_w.charAt(0);
for (i = 0; i < 16; i++) {
context_data_val = (context_data_val << 1) | (value & 1);
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.append(getCharFromInt.doFunc(context_data_val));
context_data_val = 0;
} else {
context_data_position++;
}
value = value >> 1;
}
}
context_enlargeIn--;
if (context_enlargeIn == 0) {
context_enlargeIn = powerOf2(context_numBits);
context_numBits++;
}
context_dictionaryToCreate.remove(context_w);
} else {
value = context_dictionary.get(context_w);
for (i = 0; i < context_numBits; i++) {
context_data_val = (context_data_val << 1) | (value & 1);
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.append(getCharFromInt.doFunc(context_data_val));
context_data_val = 0;
} else {
context_data_position++;
}
value = value >> 1;
}
}
context_enlargeIn--;
if (context_enlargeIn == 0) {
context_enlargeIn = powerOf2(context_numBits);
context_numBits++;
}
// Add wc to the dictionary.
context_dictionary.put(context_wc, context_dictSize++);
context_w = context_c;
}
}
// Output the code for w.
if (!context_w.isEmpty()) {
if (context_dictionaryToCreate.contains(context_w)) {
if (context_w.charAt(0) < 256) {
for (i = 0; i < context_numBits; i++) {
context_data_val = (context_data_val << 1);
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.append(getCharFromInt.doFunc(context_data_val));
context_data_val = 0;
} else {
context_data_position++;
}
}
value = context_w.charAt(0);
for (i = 0; i < 8; i++) {
context_data_val = (context_data_val << 1) | (value & 1);
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.append(getCharFromInt.doFunc(context_data_val));
context_data_val = 0;
} else {
context_data_position++;
}
value = value >> 1;
}
} else {
value = 1;
for (i = 0; i < context_numBits; i++) {
context_data_val = (context_data_val << 1) | value;
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.append(getCharFromInt.doFunc(context_data_val));
context_data_val = 0;
} else {
context_data_position++;
}
value = 0;
}
value = context_w.charAt(0);
for (i = 0; i < 16; i++) {
context_data_val = (context_data_val << 1) | (value & 1);
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.append(getCharFromInt.doFunc(context_data_val));
context_data_val = 0;
} else {
context_data_position++;
}
value = value >> 1;
}
}
context_enlargeIn--;
if (context_enlargeIn == 0) {
context_enlargeIn = powerOf2(context_numBits);
context_numBits++;
}
context_dictionaryToCreate.remove(context_w);
} else {
value = context_dictionary.get(context_w);
for (i = 0; i < context_numBits; i++) {
context_data_val = (context_data_val << 1) | (value & 1);
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.append(getCharFromInt.doFunc(context_data_val));
context_data_val = 0;
} else {
context_data_position++;
}
value = value >> 1;
}
}
context_enlargeIn--;
if (context_enlargeIn == 0) {
context_enlargeIn = powerOf2(context_numBits);
context_numBits++;
}
}
// Mark the end of the stream
value = 2;
for (i = 0; i < context_numBits; i++) {
context_data_val = (context_data_val << 1) | (value & 1);
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.append(getCharFromInt.doFunc(context_data_val));
context_data_val = 0;
} else {
context_data_position++;
}
value = value >> 1;
}
// Flush the last char
while (true) {
context_data_val = (context_data_val << 1);
if (context_data_position == bitsPerChar - 1) {
context_data.append(getCharFromInt.doFunc(context_data_val));
break;
}
else
context_data_position++;
}
return context_data.toString();
}
private static abstract class DecompressFunctionWrapper { private static abstract class DecompressFunctionWrapper {
public abstract char doFunc(int i); public abstract char doFunc(int i);
} }
protected static class DecData { protected static class DecData {
public char val; public char val;
public int position; public int position;
@ -354,34 +53,17 @@ public class LZString {
public static String f(int i) { public static String f(int i) {
return String.valueOf((char) i); return String.valueOf((char) i);
} }
public static char fc(int i) {
return (char) i;
}
public static String decompress(final String compressed) {
if (compressed == null)
return "";
if (compressed.isEmpty())
return null;
return LZString._decompress(compressed.length(), 32768, new DecompressFunctionWrapper() {
@Override
public char doFunc(int i) {
return compressed.charAt(i);
}
});
}
private static String _decompress(int length, int resetValue, DecompressFunctionWrapper getNextValue) { private static String _decompress(int length, int resetValue, DecompressFunctionWrapper getNextValue) {
List<String> dictionary = new ArrayList<String>(); List<String> dictionary = new ArrayList<>();
// TODO: is next an unused variable in original lz-string?
@SuppressWarnings("unused")
int next;
int enlargeIn = 4; int enlargeIn = 4;
int dictSize = 4; int dictSize = 4;
int numBits = 3; int numBits = 3;
String entry = ""; String entry;
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
String w; String w;
int bits, resb; int maxpower, power; int bits, resb;
int maxpower, power;
String c = null; String c = null;
DecData data = new DecData(); DecData data = new DecData();
data.val = getNextValue.doFunc(0); data.val = getNextValue.doFunc(0);
@ -393,7 +75,7 @@ public class LZString {
} }
bits = 0; bits = 0;
maxpower = (int) powerOf2(2); maxpower = powerOf2(2);
power = 1; power = 1;
while (power != maxpower) { while (power != maxpower) {
resb = data.val & data.position; resb = data.val & data.position;
@ -406,11 +88,10 @@ public class LZString {
power <<= 1; power <<= 1;
} }
switch (next = bits) { switch (bits) {
case 0: case 0:
bits = 0; maxpower = powerOf2(8);
maxpower = (int) powerOf2(8); power = 1;
power=1;
while (power != maxpower) { while (power != maxpower) {
resb = data.val & data.position; resb = data.val & data.position;
data.position >>= 1; data.position >>= 1;
@ -418,7 +99,7 @@ public class LZString {
data.position = resetValue; data.position = resetValue;
data.val = getNextValue.doFunc(data.index++); data.val = getNextValue.doFunc(data.index++);
} }
bits |= (resb>0 ? 1 : 0) * power; bits |= (resb > 0 ? 1 : 0) * power;
power <<= 1; power <<= 1;
} }
c = f(bits); c = f(bits);
@ -426,15 +107,15 @@ public class LZString {
case 1: case 1:
bits = 0; bits = 0;
maxpower = powerOf2(16); maxpower = powerOf2(16);
power=1; power = 1;
while (power!=maxpower) { while (power != maxpower) {
resb = data.val & data.position; resb = data.val & data.position;
data.position >>= 1; data.position >>= 1;
if (data.position == 0) { if (data.position == 0) {
data.position = resetValue; data.position = resetValue;
data.val = getNextValue.doFunc(data.index++); data.val = getNextValue.doFunc(data.index++);
} }
bits |= (resb>0 ? 1 : 0) * power; bits |= (resb > 0 ? 1 : 0) * power;
power <<= 1; power <<= 1;
} }
c = f(bits); c = f(bits);
@ -449,58 +130,54 @@ public class LZString {
if (data.index > length) { if (data.index > length) {
return ""; return "";
} }
bits = 0; bits = 0;
maxpower = powerOf2(numBits); maxpower = powerOf2(numBits);
power=1; power = 1;
while (power!=maxpower) { while (power != maxpower) {
resb = data.val & data.position; resb = data.val & data.position;
data.position >>= 1; data.position >>= 1;
if (data.position == 0) { if (data.position == 0) {
data.position = resetValue; data.position = resetValue;
data.val = getNextValue.doFunc(data.index++); data.val = getNextValue.doFunc(data.index++);
} }
bits |= (resb>0 ? 1 : 0) * power; bits |= (resb > 0 ? 1 : 0) * power;
power <<= 1; power <<= 1;
} }
// TODO: very strange here, c above is as char/string, here further is a int, rename "c" in the switch as "cc"
int cc; int cc;
switch (cc = bits) { switch (cc = bits) {
case 0: case 0:
bits = 0;
maxpower = powerOf2(8); maxpower = powerOf2(8);
power=1; power = 1;
while (power!=maxpower) { while (power != maxpower) {
resb = data.val & data.position; resb = data.val & data.position;
data.position >>= 1; data.position >>= 1;
if (data.position == 0) { if (data.position == 0) {
data.position = resetValue; data.position = resetValue;
data.val = getNextValue.doFunc(data.index++); data.val = getNextValue.doFunc(data.index++);
} }
bits |= (resb>0 ? 1 : 0) * power; bits |= (resb > 0 ? 1 : 0) * power;
power <<= 1; power <<= 1;
} }
dictionary.add(dictSize++, f(bits)); dictionary.add(dictSize++, f(bits));
cc = dictSize-1; cc = dictSize - 1;
enlargeIn--; enlargeIn--;
break; break;
case 1: case 1:
bits = 0; bits = 0;
maxpower = powerOf2(16); maxpower = powerOf2(16);
power=1; power = 1;
while (power!=maxpower) { while (power != maxpower) {
resb = data.val & data.position; resb = data.val & data.position;
data.position >>= 1; data.position >>= 1;
if (data.position == 0) { if (data.position == 0) {
data.position = resetValue; data.position = resetValue;
data.val = getNextValue.doFunc(data.index++); data.val = getNextValue.doFunc(data.index++);
} }
bits |= (resb>0 ? 1 : 0) * power; bits |= (resb > 0 ? 1 : 0) * power;
power <<= 1; power <<= 1;
} }
dictionary.add(dictSize++, f(bits)); dictionary.add(dictSize++, f(bits));
cc = dictSize-1; cc = dictSize - 1;
enlargeIn--; enlargeIn--;
break; break;
case 2: case 2:
@ -533,9 +210,7 @@ public class LZString {
enlargeIn = powerOf2(numBits); enlargeIn = powerOf2(numBits);
numBits++; numBits++;
} }
} }
} }
private static int powerOf2(int power) { private static int powerOf2(int power) {

Binary file not shown.

View File

@ -1 +1 @@
d585abd2ba8acc357c14da7f07a92d4e 101bd3f495cfb4cb4b3603d85d1647ea