Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/nining377/dolby_beta
Browse files Browse the repository at this point in the history
� Conflicts:
�	app/build.gradle
  • Loading branch information
nining377 committed Aug 17, 2021
2 parents ca7682a + a1b2409 commit 116d1ff
Show file tree
Hide file tree
Showing 10 changed files with 148 additions and 36 deletions.
2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ android {
applicationId "com.raincat.dolby_beta"
minSdkVersion 14
targetSdkVersion 23
versionCode 203
versionName "2.0.3"
versionCode 210
versionName "2.1.0"
}
buildTypes {
release {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.content.Context;

import com.raincat.dolby_beta.db.ExtraDao;
import com.raincat.dolby_beta.hook.AdAndUpdateHook;
import com.raincat.dolby_beta.hook.AutoSignInHook;
import com.raincat.dolby_beta.hook.BlackHook;
Expand Down Expand Up @@ -74,8 +75,10 @@ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
if (processName.equals(CloudMusicPackage.PACKAGE_NAME)) {
CloudMusicPackage.init(neteaseContext);
//UnblockMusic代理
if (Setting.isProxyEnabled())
if (Setting.isProxyEnabled()) {
ExtraDao.getInstance(neteaseContext).saveExtra("ScriptRunning", "0");
new UnblockMusicHook(neteaseContext, CloudMusicPackage.versionCode, false);
}
//黑胶
if (Setting.isBlackEnabled()) {
Tools.deleteDirectory(CloudMusicPackage.CACHE_PATH);
Expand Down
8 changes: 4 additions & 4 deletions app/src/main/java/com/raincat/dolby_beta/db/ExtraDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public static synchronized ExtraDao getInstance(Context context) {
/**
* 保存额外记录
*/
public void saveExtra(String key, String value) {
public synchronized void saveExtra(String key, String value) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
if (db.isOpen()) {
ContentValues values = new ContentValues();
Expand All @@ -49,7 +49,7 @@ public void saveExtra(String key, String value) {
/**
* 获取某个额外记录
*/
public String getExtra(String key) {
public synchronized String getExtra(String key) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
if (db.isOpen()) {
Cursor cursor = db.rawQuery("select * from " + TABLE_NAME + " where " + EXTRA_KEY + " = '" + key + "'", null);
Expand All @@ -65,7 +65,7 @@ public String getExtra(String key) {
/**
* 删除一个人的某条额外记录
*/
public void deleteExtra(String key) {
public synchronized void deleteExtra(String key) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
if (db.isOpen()) {
db.delete(TABLE_NAME, EXTRA_KEY + " = ? ", new String[]{key});
Expand All @@ -76,7 +76,7 @@ public void deleteExtra(String key) {
/**
* 删除所有额外记录
*/
public void deleteAllExtra() {
public synchronized void deleteAllExtra() {
SQLiteDatabase db = dbHelper.getWritableDatabase();
if (db.isOpen()) {
db.delete(TABLE_NAME, null, null);
Expand Down
104 changes: 77 additions & 27 deletions app/src/main/java/com/raincat/dolby_beta/hook/UnblockMusicHook.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.raincat.dolby_beta.hook;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;

Expand All @@ -12,8 +13,11 @@
import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.Arrays;
import java.util.List;

import javax.net.ssl.SSLSocketFactory;

import de.robv.android.xposed.XC_MethodHook;

import static de.robv.android.xposed.XposedBridge.hookAllConstructors;
Expand All @@ -23,7 +27,6 @@
/**
* <pre>
* author : RainCat
* org : Shenzhen JingYu Network Technology Co., Ltd.
* e-mail : nining377@gmail.com
* time : 2021/03/10
* desc : 音乐代理hook
Expand All @@ -33,26 +36,40 @@

public class UnblockMusicHook {
private final static String STOP_PROXY = "killall -9 node >/dev/null 2>&1";
private final static String START_PROXY = "./node app.js -o kuwo qq migu kugou -p 23338";
private final static String START_PROXY = "./node app.js -o kuwo qq migu kugou -a 127.0.0.1 -p 23338:23339";

private static String dataPath;
private static SSLSocketFactory socketFactory;
private static Object objectProxy;
private static Object objectSSLSocketFactory;

private final String classMainActivity = "com.netease.cloudmusic.activity.MainActivity";
private String classRealCall ;
private String classRealCall;
private String fieldHttpUrl = "url";
private String fieldProxy = "proxy";
private String fieldSSLSocketFactory;

private final List<String> whiteUrlList = Arrays.asList(
"song/enhance/player/url", "song/enhance/download/url");

private final List<String> blackUrlList = Arrays.asList("eapi/playlist/subscribe",
"163yun.com");

public UnblockMusicHook(Context context, int versionCode, boolean isPlayProcess) {
if (versionCode >= 7001080) {
classRealCall = "okhttp3.internal.connection.RealCall";
fieldSSLSocketFactory = "sslSocketFactoryOrNull";
} else if (versionCode >= 138) {
classRealCall = "okhttp3.RealCall";
fieldSSLSocketFactory = "sslSocketFactory";
} else {
classRealCall = "okhttp3.z";
fieldSSLSocketFactory = "o";
fieldHttpUrl = "a";
fieldProxy = "d";
}

dataPath = context.getFilesDir().getAbsolutePath() + File.separator + "script";
final Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 23338));
hookAllConstructors(findClass(classRealCall, context.getClassLoader()), new XC_MethodHook() {
@Override
Expand All @@ -67,13 +84,40 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
proxyField.setAccessible(true);

Object urlObj = urlField.get(request);
if (urlObj.toString().contains("song/enhance/player/url") || urlObj.toString().contains("song/enhance/download/url")) {

for (String url : blackUrlList) {
if (urlObj.toString().contains(url)) {
return;
}
}

if (Setting.isWhiteEnabled()) {
for (String url : whiteUrlList) {
if (urlObj.toString().contains(url)) {
if (ExtraDao.getInstance(context).getExtra("ScriptRunning").equals("1"))
proxyField.set(client, proxy);
else
Tools.showToastOnLooper(context, "node未成功运行,请到模块内选择正确的脚本与Node路径,若已使用存储重定向等APP请保证网易云音乐也可访问到脚本路径!");
break;
}
}
} else {
Field sslSocketFactoryField = client.getClass().getDeclaredField(fieldSSLSocketFactory);
sslSocketFactoryField.setAccessible(true);
if (objectProxy == null)
objectProxy = proxyField.get(client);
if (objectSSLSocketFactory == null)
objectSSLSocketFactory = sslSocketFactoryField.get(client);

if (ExtraDao.getInstance(context).getExtra("ScriptRunning").equals("0")) {
Tools.showToastOnLooper(context, "node未运行,请保证脚本与Node文件路径正确!");
} else
proxyField.set(client, objectProxy);
sslSocketFactoryField.set(client, objectSSLSocketFactory);
} else {
if (socketFactory == null)
socketFactory = Tools.getSLLContext(dataPath + File.separator + "ca.crt").getSocketFactory();
proxyField.set(client, proxy);
} else {
proxyField.set(client, null);
sslSocketFactoryField.set(client, socketFactory);
}
}
}
}
Expand All @@ -85,25 +129,21 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
findAndHookMethod(classMainActivity, context.getClassLoader(), "onCreate", Bundle.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) {
ExtraDao.getInstance(context).saveExtra("ScriptRunning", "0");
initScript(context);
final Context neteaseContext = (Context) param.thisObject;
initScript(neteaseContext);
}
});

findAndHookMethod(classMainActivity, context.getClassLoader(), "onDestroy", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
protected void afterHookedMethod(MethodHookParam param) {
Command stop = new Command(0, STOP_PROXY);
Tools.shell(context, stop);
dataPath = null;
}
});
}

private void initScript(final Context c) {
if (dataPath != null)
return;

long scriptLastUpdateTime = Long.parseLong(ExtraDao.getInstance(c).getExtra("script_time"));
long nodeSize = Long.parseLong(ExtraDao.getInstance(c).getExtra("node_size"));
String scriptFilePath = Setting.getScriptFile(), nodeFilePath = Setting.getNodeFile();
Expand All @@ -115,7 +155,6 @@ else if (!scriptFile.exists() && scriptLastUpdateTime < 0)
else if (!nodeFile.exists())
Tools.showToastOnLooper(c, "node文件不存在!");
else {
dataPath = c.getFilesDir().getAbsolutePath() + File.separator + "script";
File dataFile = new File(dataPath);
if (!dataFile.exists())
dataFile.mkdirs();
Expand All @@ -134,19 +173,30 @@ else if (!nodeFile.exists())
Tools.shell(c, auth);
}

Command start = new Command(0, STOP_PROXY, "cd " + dataPath, START_PROXY) {
@Override
public void commandOutput(int id, String line) {
if (line.contains("Error")) {
Tools.showToastOnLooper(c, "运行失败,错误为:" + line);
} else if (line.contains("HTTP Server running")) {
Tools.showToastOnLooper(c, "UnblockNeteaseMusic运行成功");
ExtraDao.getInstance(context).saveExtra("ScriptRunning", "1");
startScrip(c);
}
}

private void startScrip(final Context c) {
Command start = new Command(0, STOP_PROXY, "cd " + dataPath, START_PROXY) {
@Override
public void commandOutput(int id, String line) {
if (line.contains("Error")) {
ExtraDao.getInstance(context).saveExtra("ScriptRunning", "0");
Tools.showToastOnLooper(c, "运行失败,错误为:" + line);
} else if (line.contains("HTTP Server running")) {
ExtraDao.getInstance(context).saveExtra("ScriptRunning", "1");
Tools.showToastOnLooper(c, "UnblockNeteaseMusic运行成功");
} else if (line.contains("Killed")) {
ExtraDao.getInstance(context).saveExtra("ScriptRunning", "0");
if (!((Activity) c).isFinishing()) {
Tools.showToastOnLooper(c, "Node被Killed,可能手机运存已耗尽,正在尝试重启……");
startScrip(c);
}
}
};
Tools.shell(c, start);
}
}
};
Tools.shell(c, start);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
/**
* <pre>
* author : RainCat
* org : Shenzhen JingYu Network Technology Co., Ltd.
* e-mail : nining377@gmail.com
* time : 2021/03/13
* desc : 说明
Expand Down
7 changes: 7 additions & 0 deletions app/src/main/java/com/raincat/dolby_beta/utils/Setting.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ public static boolean isQualityEnabled() {
return getModuleSharedPreferences().getBoolean(getModuleResString(R.string.quality_key), defaultValue);
}

public static boolean isWhiteEnabled() {
String valueString = getModuleResString(R.string.white_default_value);
boolean defaultValue = Boolean.parseBoolean(valueString);

return getModuleSharedPreferences().getBoolean(getModuleResString(R.string.white_key), defaultValue);
}

public static boolean isForceEnabled() {
String valueString = getModuleResString(R.string.force_default_value);
boolean defaultValue = Boolean.parseBoolean(valueString);
Expand Down
41 changes: 41 additions & 0 deletions app/src/main/java/com/raincat/dolby_beta/utils/Tools.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,24 @@
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.reflect.Method;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeoutException;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

/**
* <pre>
* author : RainCat
Expand Down Expand Up @@ -335,6 +345,37 @@ public static boolean unZipFile(String zipFileString, String outPathString) {
return true;
}

/**
* 获取CA证书
*/
public static SSLContext getSLLContext(String caPath) {
SSLContext sslContext = null;
try {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
File ca = new File(caPath);
InputStream certificate = new FileInputStream(ca);
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
String certificateAlias = Integer.toString(0);
keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));
sslContext = SSLContext.getInstance("TLS");
final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
} catch (CertificateException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return sslContext;
}

/**
* 判断是否为64bit手机
*
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@
<string name="quality_title">优先获取无损音质</string>
<string name="quality_summary">仅能从酷我音源获取无损音质</string>

<string name="white_key" translatable="false">white</string>
<string name="white_default_value">true</string>
<string name="white_title">白名单模式</string>
<string name="white_summary">白名单:仅对播放及下载api进行代理,其他功能(不变灰等)由杜比大喇叭完成\n~建议仅在白名单模式无效时关闭选项~</string>

<string name="script_key" translatable="false">script</string>
<string name="script_title">脚本ZIP压缩包路径</string>

Expand Down
7 changes: 7 additions & 0 deletions app/src/main/res/xml/pref_general.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@
android:summary="@string/quality_summary"
android:title="@string/quality_title" />

<CheckBoxPreference
android:defaultValue="@string/white_default_value"
android:dependency="@string/proxy_key"
android:key="@string/white_key"
android:summary="@string/white_summary"
android:title="@string/white_title" />

<Preference
android:dependency="@string/proxy_key"
android:key="@string/script_key"
Expand Down

0 comments on commit 116d1ff

Please sign in to comment.