diff --git a/app/build.gradle b/app/build.gradle index c01c6f32..5dab3ec0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -35,5 +35,6 @@ dependencies { implementation 'com.squareup.okhttp3:okhttp:4.10.0' implementation 'com.google.code.gson:gson:2.9.1' implementation 'cn.wanghaomiao:JsoupXpath:2.5.1' + implementation 'com.google.zxing:core:3.5.0' implementation 'org.jsoup:jsoup:1.15.3' } \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index b6f6c69f..d7db20cc 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -20,6 +20,12 @@ -keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken -keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken +# Zxing +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + # OkHttp -keep class okio.**{*;} -keep class okhttp3.**{*;} diff --git a/app/src/main/java/com/github/catvod/bean/ali/Code.java b/app/src/main/java/com/github/catvod/bean/ali/Code.java new file mode 100644 index 00000000..69141158 --- /dev/null +++ b/app/src/main/java/com/github/catvod/bean/ali/Code.java @@ -0,0 +1,60 @@ +package com.github.catvod.bean.ali; + +import com.google.gson.Gson; +import com.google.gson.annotations.SerializedName; + +public class Code { + + @SerializedName("data") + private Data data; + @SerializedName("pds_login_result") + private Data result; + + public static Code objectFrom(String str) { + try { + return new Gson().fromJson(str, Code.class); + } catch (Exception e) { + return new Code(); + } + } + + public Data getData() { + return data == null ? new Data() : data; + } + + public Data getResult() { + return result == null ? new Data() : result; + } + + public boolean hasToken() { + return getResult().getRefreshToken().length() > 0; + } + + public static class Data { + + @SerializedName("t") + private String t; + @SerializedName("ck") + private String ck; + @SerializedName("codeContent") + private String codeContent; + @SerializedName("refreshToken") + private String refreshToken; + + public String getT() { + return t; + } + + public String getCk() { + return ck; + } + + public String getCodeContent() { + return codeContent == null ? "" : codeContent; + } + + public String getRefreshToken() { + return refreshToken == null ? "" : refreshToken; + } + } +} diff --git a/app/src/main/java/com/github/catvod/demo/MainActivity.java b/app/src/main/java/com/github/catvod/demo/MainActivity.java index 61a98f45..2a3de8c1 100644 --- a/app/src/main/java/com/github/catvod/demo/MainActivity.java +++ b/app/src/main/java/com/github/catvod/demo/MainActivity.java @@ -12,7 +12,6 @@ public class MainActivity extends Activity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new Thread(() -> { - }).start(); } } \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/spider/Ali.java b/app/src/main/java/com/github/catvod/spider/Ali.java index 69044b68..2eab0b62 100644 --- a/app/src/main/java/com/github/catvod/spider/Ali.java +++ b/app/src/main/java/com/github/catvod/spider/Ali.java @@ -1,25 +1,22 @@ package com.github.catvod.spider; -import android.graphics.BitmapFactory; -import android.graphics.Color; -import android.os.Handler; -import android.os.Looper; +import android.os.SystemClock; import android.text.TextUtils; -import android.util.Base64; import android.view.Gravity; import android.view.View; -import android.webkit.WebView; -import android.webkit.WebViewClient; import android.widget.FrameLayout; import android.widget.ImageView; import com.github.catvod.bean.Result; import com.github.catvod.bean.Vod; +import com.github.catvod.bean.ali.Code; import com.github.catvod.bean.ali.Item; import com.github.catvod.net.OkHttpUtil; import com.github.catvod.utils.Misc; import com.github.catvod.utils.Prefers; +import com.github.catvod.utils.QRCode; import com.github.catvod.utils.Trans; +import com.google.gson.JsonObject; import org.json.JSONArray; import org.json.JSONException; @@ -33,6 +30,9 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -42,6 +42,7 @@ import java.util.regex.Pattern; public class Ali { private final Pattern pattern = Pattern.compile("www.aliyundrive.com/s/([^/]+)(/folder/([^/]+))?"); + private ScheduledExecutorService service; private static String accessToken; private String refreshToken; private ImageView code; @@ -90,7 +91,7 @@ public class Ali { String fileId = ids[2]; String sub = getSub(shareId, shareToken, ids); refreshAccessToken(); - if (TextUtils.isEmpty(accessToken)) return ""; + while (TextUtils.isEmpty(accessToken)) SystemClock.sleep(250); if (flag.equals("原畫")) { return Result.get().url(getDownloadUrl(shareId, shareToken, fileId)).sub(sub).header(getHeaders()).string(); } else { @@ -278,42 +279,37 @@ public class Ali { return result; } - private void getToken() { - Misc.loadWebView("https://easy-token.cooluc.com/", new WebViewClient() { - @Override - public void onLoadResource(WebView view, String url) { - if (url.endsWith("/ck")) { - new Handler(Looper.getMainLooper()).postDelayed(() -> view.evaluateJavascript("document.getElementsByTagName('input')[0].value", value -> saveToken(value)), 1000); - } else if (url.endsWith("/qr")) { - new Handler(Looper.getMainLooper()).postDelayed(() -> view.evaluateJavascript("document.getElementsByTagName('img')[0].src", value -> showQRCode(value)), 3000); - } - } - }); + public void getToken() { + if (service != null) service.shutdownNow(); + Code code = Code.objectFrom(OkHttpUtil.string("https://easy-token.cooluc.com/qr")); + Init.run(() -> showQRCode(code.getData().getCodeContent())); + service = Executors.newScheduledThreadPool(2); + service.scheduleAtFixedRate(() -> { + JsonObject params = new JsonObject(); + params.addProperty("t", code.getData().getT()); + params.addProperty("ck", code.getData().getCk()); + Code result = Code.objectFrom(OkHttpUtil.postJson("https://easy-token.cooluc.com/ck", params.toString())); + if (result.hasToken()) saveToken(result.getResult().getRefreshToken()); + }, 1, 1, TimeUnit.SECONDS); } private void saveToken(String value) { - if (value.length() == 2) return; - Prefers.put("token", refreshToken = value.replace("\"", "")); - Init.show("請重新進入播放頁"); - code.setVisibility(View.GONE); - Misc.removeView(code); + Prefers.put("token", refreshToken = value); + Init.run(() -> code.setVisibility(View.GONE)); + service.shutdownNow(); } - private void showQRCode(String value) { - if (!value.contains("base64,")) return; - byte[] bytes = Base64.decode(value.split("base64,")[1], Base64.DEFAULT); - FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(Misc.dp2px(250), Misc.dp2px(250)); + private void showQRCode(String text) { + FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT); params.gravity = Gravity.CENTER; - Misc.addView(code = create(bytes), params); + Misc.addView(code = create(text), params); Init.show("請使用阿里雲盤 App 掃描二維碼"); } - private ImageView create(byte[] bytes) { + private ImageView create(String value) { ImageView view = new ImageView(Init.context()); - view.setBackgroundColor(Color.WHITE); view.setScaleType(ImageView.ScaleType.CENTER_CROP); - view.setPadding(Misc.dp2px(20), Misc.dp2px(20), Misc.dp2px(20), Misc.dp2px(20)); - view.setImageBitmap(BitmapFactory.decodeByteArray(bytes, 0, bytes.length)); + view.setImageBitmap(QRCode.getBitmap(value, 250, 2)); return view; } } \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/utils/QRCode.java b/app/src/main/java/com/github/catvod/utils/QRCode.java new file mode 100644 index 00000000..2afc6c16 --- /dev/null +++ b/app/src/main/java/com/github/catvod/utils/QRCode.java @@ -0,0 +1,43 @@ +package com.github.catvod.utils; + +import android.graphics.Bitmap; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.MultiFormatWriter; +import com.google.zxing.common.BitMatrix; + +import java.util.EnumMap; +import java.util.Map; + +public class QRCode { + + private static final int WHITE = 0xFFFFFFFF; + private static final int BLACK = 0xFF000000; + + public static Bitmap createBitmap(BitMatrix matrix) { + int width = matrix.getWidth(); + int height = matrix.getHeight(); + int[] pixels = new int[width * height]; + for (int y = 0; y < height; y++) { + int offset = y * width; + for (int x = 0; x < width; x++) { + pixels[offset + x] = matrix.get(x, y) ? BLACK : WHITE; + } + } + Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + bitmap.setPixels(pixels, 0, width, 0, 0, width, height); + return bitmap; + } + + public static Bitmap getBitmap(String contents, int size, int margin) { + try { + Map hints = new EnumMap<>(EncodeHintType.class); + hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); + hints.put(EncodeHintType.MARGIN, margin); + return createBitmap(new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, Misc.dp2px(size), Misc.dp2px(size), hints)); + } catch (Exception e) { + return null; + } + } +} diff --git a/jar/custom_spider.jar b/jar/custom_spider.jar index 994f24e0..8bd6c111 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 34af081e..cf74e17e 100644 --- a/jar/custom_spider.jar.md5 +++ b/jar/custom_spider.jar.md5 @@ -1 +1 @@ -6aa710655b59e0b3f88a283a3c4668ec +7071a7598ea9bffccc4fc76684f9b529