diff --git a/.gitignore b/.gitignore index 6fd1e22c..8365f0a7 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ *.aar *.ap_ *.aab +release/ +debug/ # Files for the ART/Dalvik VM *.dex diff --git a/app/.gitignore b/app/.gitignore index 42afabfd..02e8c3d4 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -1 +1,85 @@ -/build \ No newline at end of file +# Built application files +*.apk +*.ap_ +*.aab + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +!/app/libnode/bin/ +gen/ +out/ +# Uncomment the following line in case you need and you don't have the release build type files in your app +# release/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# IntelliJ +*.iml +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/assetWizardSettings.xml +.idea/dictionaries +.idea/libraries +# Android Studio 3 in .gitignore file. +.idea/caches +.idea/modules.xml +# Comment next line if keeping position of elements in Navigation Editor is relevant for you +.idea/navEditor.xml + +# Keystore files +# Uncomment the following lines if you do not want to check your keystore files in. +#*.jks +#*.keystore + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild +.cxx/ + +# Google Services (e.g. APIs or Firebase) +# google-services.json + +# Freeline +freeline.py +freeline/ +freeline_project_description.json + +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +fastlane/readme.md + +# Version control +vcs.xml + +# lint +lint/intermediates/ +lint/generated/ +lint/outputs/ +lint/tmp/ +# lint/reports/ \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 6afc2a9e..59f01c04 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "com.raincat.dolby_beta" minSdkVersion 21 targetSdkVersion 29 - versionCode 350 - versionName "3.5.0" + versionCode 351 + versionName "3.5.1" ndk { abiFilters "arm64-v8a" diff --git a/app/src/main/assets/UnblockNeteaseMusic.zip b/app/src/main/assets/UnblockNeteaseMusic.zip index a7a13dd6..07d64bb9 100644 Binary files a/app/src/main/assets/UnblockNeteaseMusic.zip and b/app/src/main/assets/UnblockNeteaseMusic.zip differ diff --git a/app/src/main/java/com/raincat/dolby_beta/helper/EAPIHelper.java b/app/src/main/java/com/raincat/dolby_beta/helper/EAPIHelper.java index 982817fd..0c3abf4a 100644 --- a/app/src/main/java/com/raincat/dolby_beta/helper/EAPIHelper.java +++ b/app/src/main/java/com/raincat/dolby_beta/helper/EAPIHelper.java @@ -3,11 +3,13 @@ import com.google.gson.Gson; import com.ndktools.javamd5.core.MD5; import com.raincat.dolby_beta.model.CloudHeader; +import com.raincat.dolby_beta.model.NeteaseSongListBean; import com.raincat.dolby_beta.net.Http; import com.raincat.dolby_beta.utils.NeteaseAES2; import org.json.JSONObject; +import java.util.ArrayList; import java.util.HashMap; import java.util.Random; import java.util.regex.Pattern; @@ -23,6 +25,33 @@ */ public class EAPIHelper { + private static final Gson gson = new Gson(); + + /** + * 解除下载加密 + */ + public static String modifyPlayer(String original) { + NeteaseSongListBean listBean = gson.fromJson(original, NeteaseSongListBean.class); + + NeteaseSongListBean modifyListBean = new NeteaseSongListBean(); + modifyListBean.setCode(200); + modifyListBean.setData(new ArrayList<>()); + for (NeteaseSongListBean.DataBean dataBean : listBean.getData()) { + //flag与8非0为云盘歌曲 + if ((dataBean.getFlag() & 0x8) == 0) { + + dataBean.setFee(0); + dataBean.setFlag(0); + dataBean.setPayed(0); + dataBean.setFreeTrialInfo(null); + if (dataBean.getUrl().contains("?")) + dataBean.setUrl(dataBean.getUrl().substring(0, dataBean.getUrl().indexOf("?"))); + } + modifyListBean.getData().add(dataBean); + } + return gson.toJson(modifyListBean); + } + /** * 收藏 */ diff --git a/app/src/main/java/com/raincat/dolby_beta/helper/ScriptHelper.java b/app/src/main/java/com/raincat/dolby_beta/helper/ScriptHelper.java index d492415a..b65ec6af 100644 --- a/app/src/main/java/com/raincat/dolby_beta/helper/ScriptHelper.java +++ b/app/src/main/java/com/raincat/dolby_beta/helper/ScriptHelper.java @@ -85,7 +85,7 @@ public static void startHttpProxyMode(final Context context) { public static void startScript(final Context context) { if (TextUtils.isEmpty(nodeLibPath)) { nodeLibPath = TextUtils.isEmpty(modulePath) ? "" : modulePath.substring(0, modulePath.lastIndexOf('/')); - nodeLibPath = "export PATH=$PATH:" + nodeLibPath + "/lib/arm64:" + modulePath + "!/lib/arm64-v8a"; + nodeLibPath = "export PATH=$PATH:" + nodeLibPath + "/lib/arm64:" + modulePath + "!/lib/arm64-v8a:" + context.getApplicationInfo().nativeLibraryDir; } String START_PROXY = String.format("export ENABLE_FLAC=%s&&export MIN_BR=%s&&libnode.so app.js -a 127.0.0.1 -o %s -p %s", diff --git a/app/src/main/java/com/raincat/dolby_beta/hook/EAPIHook.java b/app/src/main/java/com/raincat/dolby_beta/hook/EAPIHook.java index 0064d363..191322b4 100644 --- a/app/src/main/java/com/raincat/dolby_beta/hook/EAPIHook.java +++ b/app/src/main/java/com/raincat/dolby_beta/hook/EAPIHook.java @@ -50,7 +50,17 @@ protected void afterHookedMethod(MethodHookParam param) throws Throwable { return; String path = uri.getPath(); - if (path.contains("v1/playlist/manipulate/tracks")) { + if (path.contains("song/enhance/player/url")) { + original = EAPIHelper.modifyPlayer(original); + } else if (path.contains("song/enhance/download/url")) { + JSONObject jsonObject = new JSONObject(original); + JSONObject object = jsonObject.getJSONObject("data"); + JSONArray array = new JSONArray(); + array.put(object); + jsonObject.put("data", array); + original = EAPIHelper.modifyPlayer(jsonObject.toString()) + .replace("[", "").replace("]", ""); + } else if (path.contains("v1/playlist/manipulate/tracks")) { original = EAPIHelper.modifyManipulate(ClassHelper.HttpParams.getParams(context, eapi), original); } else if (path.contains("song/like")) { original = EAPIHelper.modifyLike(ClassHelper.HttpParams.getParams(context, eapi), original); diff --git a/app/src/main/java/com/raincat/dolby_beta/hook/ProxyHook.java b/app/src/main/java/com/raincat/dolby_beta/hook/ProxyHook.java index 25e02414..7701c8ac 100644 --- a/app/src/main/java/com/raincat/dolby_beta/hook/ProxyHook.java +++ b/app/src/main/java/com/raincat/dolby_beta/hook/ProxyHook.java @@ -86,14 +86,30 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable { }); Class okHttpClientBuilderClass = XposedHelpers.findClassIfExists("okhttp3.OkHttpClient$Builder", context.getClassLoader()); - if (okHttpClientBuilderClass != null) + if (okHttpClientBuilderClass != null) { XposedBridge.hookAllMethods(okHttpClientBuilderClass, "addInterceptor", new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); - param.setResult(param.thisObject); + if (param.args[0].getClass().getName().contains("com.netease.cloudmusic.network.cronet")) + param.setResult(param.thisObject); +// XposedBridge.hookAllMethods(param.args[0].getClass(), "intercept", new XC_MethodHook() { +// @Override +// protected void beforeHookedMethod(MethodHookParam param) throws Throwable { +// super.beforeHookedMethod(param); +// Object object = param.args[0]; +// if (object != null && object.getClass().getName().contains("Chain")) { +// Object request = XposedHelpers.callMethod(object, "request"); +// if (request.toString().contains("song/enhance/player/url") || request.toString().contains("song/enhance/download/url")) { +// Object response = XposedHelpers.callMethod(object, "proceed", request); +// param.setResult(response); +// } +// } +// } +// }); } }); + } if (isPlayProcess) findAndHookMethod("com.netease.cloudmusic.service.PlayService", context.getClassLoader(), "onCreate", new XC_MethodHook() {