mirror of
https://github.com/areteruhiro/LIME-beta-hiro.git
synced 2025-02-06 05:21:37 +09:00
parent
c6d38224bb
commit
4e88b41482
@ -33,7 +33,8 @@ public class LimeOptions {
|
|||||||
public Option blockTracking = new Option("block_tracking", R.string.switch_block_tracking, false);
|
public Option blockTracking = new Option("block_tracking", R.string.switch_block_tracking, false);
|
||||||
public Option stopVersionCheck = new Option("stop_version_check", R.string.switch_stop_version_check, false);
|
public Option stopVersionCheck = new Option("stop_version_check", R.string.switch_stop_version_check, false);
|
||||||
public Option outputCommunication = new Option("output_communication", R.string.switch_output_communication, false);
|
public Option outputCommunication = new Option("output_communication", R.string.switch_output_communication, false);
|
||||||
|
public Option Archived = new Option("Archived_message", R.string.switch_archived, false);
|
||||||
|
|
||||||
public Option[] options = {
|
public Option[] options = {
|
||||||
removeVoom,
|
removeVoom,
|
||||||
removeWallet,
|
removeWallet,
|
||||||
@ -50,6 +51,7 @@ public class LimeOptions {
|
|||||||
openInBrowser,
|
openInBrowser,
|
||||||
preventMarkAsRead,
|
preventMarkAsRead,
|
||||||
preventUnsendMessage,
|
preventUnsendMessage,
|
||||||
|
Archived,
|
||||||
sendMuteMessage,
|
sendMuteMessage,
|
||||||
removeKeepUnread,
|
removeKeepUnread,
|
||||||
blockTracking,
|
blockTracking,
|
||||||
|
@ -11,6 +11,7 @@ import de.robv.android.xposed.callbacks.XC_InitPackageResources;
|
|||||||
import de.robv.android.xposed.callbacks.XC_LayoutInflated;
|
import de.robv.android.xposed.callbacks.XC_LayoutInflated;
|
||||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||||
import io.github.chipppppppppp.lime.hooks.AddRegistrationOptions;
|
import io.github.chipppppppppp.lime.hooks.AddRegistrationOptions;
|
||||||
|
import io.github.chipppppppppp.lime.hooks.Archived;
|
||||||
import io.github.chipppppppppp.lime.hooks.BlockTracking;
|
import io.github.chipppppppppp.lime.hooks.BlockTracking;
|
||||||
import io.github.chipppppppppp.lime.hooks.CheckHookTargetVersion;
|
import io.github.chipppppppppp.lime.hooks.CheckHookTargetVersion;
|
||||||
import io.github.chipppppppppp.lime.hooks.Constants;
|
import io.github.chipppppppppp.lime.hooks.Constants;
|
||||||
@ -61,7 +62,8 @@ public class Main implements IXposedHookLoadPackage, IXposedHookInitPackageResou
|
|||||||
new KeepUnread(),
|
new KeepUnread(),
|
||||||
new BlockTracking(),
|
new BlockTracking(),
|
||||||
new ModifyResponse(),
|
new ModifyResponse(),
|
||||||
new OutputRequest()
|
new OutputRequest(),
|
||||||
|
new Archived()
|
||||||
};
|
};
|
||||||
|
|
||||||
public void handleLoadPackage(@NonNull XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
|
public void handleLoadPackage(@NonNull XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
|
||||||
|
@ -0,0 +1,229 @@
|
|||||||
|
package io.github.chipppppppppp.lime.hooks;
|
||||||
|
|
||||||
|
import static io.github.chipppppppppp.lime.Main.limeOptions;
|
||||||
|
|
||||||
|
import android.app.AndroidAppHelper;
|
||||||
|
import android.app.Application;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.robv.android.xposed.XC_MethodHook;
|
||||||
|
import de.robv.android.xposed.XposedBridge;
|
||||||
|
import de.robv.android.xposed.XposedHelpers;
|
||||||
|
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||||
|
import io.github.chipppppppppp.lime.LimeOptions;
|
||||||
|
|
||||||
|
public class Archived implements IHook {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hook(LimeOptions limeOptions, XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
|
||||||
|
if (!limeOptions.Archived.checked) return;
|
||||||
|
|
||||||
|
XposedBridge.hookAllMethods(Application.class, "onCreate", new XC_MethodHook() {
|
||||||
|
@Override
|
||||||
|
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
|
||||||
|
Application appContext = (Application) param.thisObject;
|
||||||
|
if (appContext == null) return;
|
||||||
|
|
||||||
|
File dbFile = appContext.getDatabasePath("naver_line");
|
||||||
|
if (!dbFile.exists()) return;
|
||||||
|
|
||||||
|
SQLiteDatabase.OpenParams dbParams = new SQLiteDatabase.OpenParams.Builder()
|
||||||
|
.addOpenFlags(SQLiteDatabase.OPEN_READWRITE)
|
||||||
|
.build();
|
||||||
|
SQLiteDatabase db = SQLiteDatabase.openDatabase(dbFile, dbParams);
|
||||||
|
|
||||||
|
hookSAMethod(loadPackageParam, db, appContext);
|
||||||
|
hookMessageDeletion(loadPackageParam, appContext, db, appContext);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hookMessageDeletion(XC_LoadPackage.LoadPackageParam loadPackageParam, Context context, SQLiteDatabase db, Context moduleContext) {
|
||||||
|
if (!limeOptions.Archived.checked) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
XposedBridge.hookAllMethods(
|
||||||
|
loadPackageParam.classLoader.loadClass(Constants.REQUEST_HOOK.className),
|
||||||
|
Constants.REQUEST_HOOK.methodName,
|
||||||
|
new XC_MethodHook() {
|
||||||
|
@Override
|
||||||
|
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
|
||||||
|
String paramValue = param.args[1].toString();
|
||||||
|
String talkId = extractTalkId(paramValue);
|
||||||
|
if (talkId == null) return;
|
||||||
|
|
||||||
|
if (paramValue.contains("hidden:true")) {
|
||||||
|
saveTalkIdToFile(talkId, context);
|
||||||
|
} else if (paramValue.contains("hidden:false")) {
|
||||||
|
deleteTalkIdFromFile(talkId, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateArchivedChatsFromFile(db, context, moduleContext);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (ClassNotFoundException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteTalkIdFromFile(String talkId, Context moduleContext) {
|
||||||
|
File file = new File(moduleContext.getFilesDir(), "hidelist.txt");
|
||||||
|
if (!file.exists()) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
List<String> lines = new ArrayList<>();
|
||||||
|
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
if (!line.trim().equals(talkId)) {
|
||||||
|
lines.add(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
|
||||||
|
for (String remainingLine : lines) {
|
||||||
|
writer.write(remainingLine);
|
||||||
|
writer.newLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hookSAMethod(XC_LoadPackage.LoadPackageParam loadPackageParam, SQLiteDatabase db, Context context) {
|
||||||
|
Class<?> targetClass = XposedHelpers.findClass("SA.Q", loadPackageParam.classLoader);
|
||||||
|
|
||||||
|
XposedBridge.hookAllMethods(targetClass, "invokeSuspend", new XC_MethodHook() {
|
||||||
|
@Override
|
||||||
|
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
|
||||||
|
Context appContext = AndroidAppHelper.currentApplication();
|
||||||
|
if (appContext == null) return;
|
||||||
|
|
||||||
|
File dbFile = appContext.getDatabasePath("naver_line");
|
||||||
|
if (!dbFile.exists()) return;
|
||||||
|
|
||||||
|
SQLiteDatabase.OpenParams dbParams = new SQLiteDatabase.OpenParams.Builder()
|
||||||
|
.addOpenFlags(SQLiteDatabase.OPEN_READWRITE)
|
||||||
|
.build();
|
||||||
|
SQLiteDatabase db = SQLiteDatabase.openDatabase(dbFile, dbParams);
|
||||||
|
|
||||||
|
List<String> chatIds = readChatIdsFromFile(appContext, context);
|
||||||
|
for (String chatId : chatIds) {
|
||||||
|
if (!chatId.isEmpty()) {
|
||||||
|
updateIsArchived(db, chatId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (db != null) db.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> readChatIdsFromFile(Context context, Context moduleContext) {
|
||||||
|
List<String> chatIds = new ArrayList<>();
|
||||||
|
File file = new File(moduleContext.getFilesDir(), "hidelist.txt");
|
||||||
|
|
||||||
|
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
chatIds.add(line.trim());
|
||||||
|
}
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return chatIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveTalkIdToFile(String talkId, Context moduleContext) {
|
||||||
|
File file = new File(moduleContext.getFilesDir(), "hidelist.txt");
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!file.exists()) file.createNewFile();
|
||||||
|
|
||||||
|
List<String> existingIds = new ArrayList<>();
|
||||||
|
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
existingIds.add(line.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!existingIds.contains(talkId.trim())) {
|
||||||
|
try (FileWriter writer = new FileWriter(file, true)) {
|
||||||
|
writer.write(talkId + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateArchivedChatsFromFile(SQLiteDatabase db, Context context, Context moduleContext) {
|
||||||
|
File file = new File(moduleContext.getFilesDir(), "hidelist.txt");
|
||||||
|
if (!file.exists()) return;
|
||||||
|
|
||||||
|
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||||
|
String chatId;
|
||||||
|
while ((chatId = reader.readLine()) != null) {
|
||||||
|
chatId = chatId.trim();
|
||||||
|
if (!chatId.isEmpty()) {
|
||||||
|
updateIsArchived(db, chatId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String extractTalkId(String paramValue) {
|
||||||
|
String requestPrefix = "setChatHiddenStatusRequest:SetChatHiddenStatusRequest(reqSeq:0, chatMid:";
|
||||||
|
int startIndex = paramValue.indexOf(requestPrefix);
|
||||||
|
if (startIndex == -1) return null;
|
||||||
|
|
||||||
|
int chatMidStartIndex = startIndex + requestPrefix.length();
|
||||||
|
int endIndex = paramValue.indexOf(",", chatMidStartIndex);
|
||||||
|
if (endIndex == -1) endIndex = paramValue.indexOf(")", chatMidStartIndex);
|
||||||
|
|
||||||
|
return endIndex != -1 ? paramValue.substring(chatMidStartIndex, endIndex).trim() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String queryDatabase(SQLiteDatabase db, String query, String... selectionArgs) {
|
||||||
|
if (db == null) return null;
|
||||||
|
|
||||||
|
try (Cursor cursor = db.rawQuery(query, selectionArgs)) {
|
||||||
|
if (cursor.moveToFirst()) return cursor.getString(0);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDatabase(SQLiteDatabase db, String query, Object... bindArgs) {
|
||||||
|
if (db == null) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
db.beginTransaction();
|
||||||
|
db.execSQL(query, bindArgs);
|
||||||
|
db.setTransactionSuccessful();
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
} finally {
|
||||||
|
db.endTransaction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateIsArchived(SQLiteDatabase db, String chatId) {
|
||||||
|
String updateQuery = "UPDATE chat SET is_archived = 1 WHERE chat_id = ?";
|
||||||
|
updateDatabase(db, updateQuery, chatId);
|
||||||
|
|
||||||
|
String selectQuery = "SELECT is_archived FROM chat WHERE chat_id = ?";
|
||||||
|
queryDatabase(db, selectQuery, chatId);
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,7 @@
|
|||||||
<string name="spoof_android_id_risk">Android ID の偽装は自己責任です</string>
|
<string name="spoof_android_id_risk">Android ID の偽装は自己責任です</string>
|
||||||
<string name="incompatible_version">バージョン不適合のため一部機能が利用できません</string>
|
<string name="incompatible_version">バージョン不適合のため一部機能が利用できません</string>
|
||||||
<string name="switch_android_secondary">最大バージョンに偽装</string>
|
<string name="switch_android_secondary">最大バージョンに偽装</string>
|
||||||
|
<string name="switch_archived">非表示にしたチャットの再表示を無効化</string>
|
||||||
<string name="switch_unembed_options">設定を LINE に埋め込まない (設定は同期されません)</string>
|
<string name="switch_unembed_options">設定を LINE に埋め込まない (設定は同期されません)</string>
|
||||||
<string name="switch_remove_voom">VOOM アイコンを削除</string>
|
<string name="switch_remove_voom">VOOM アイコンを削除</string>
|
||||||
<string name="switch_remove_wallet">ウォレットアイコンを削除</string>
|
<string name="switch_remove_wallet">ウォレットアイコンを削除</string>
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
<string name="spoof_android_id_risk">Spoofing Android ID is at your own risk</string>
|
<string name="spoof_android_id_risk">Spoofing Android ID is at your own risk</string>
|
||||||
<string name="incompatible_version">Some functions are not available due to version incompatibility</string>
|
<string name="incompatible_version">Some functions are not available due to version incompatibility</string>
|
||||||
<string name="switch_android_secondary">Disguise as the highest version</string>
|
<string name="switch_android_secondary">Disguise as the highest version</string>
|
||||||
|
<string name="switch_archived">Disable unhiding hidden chats</string>
|
||||||
<string name="switch_unembed_options">Do not embed options in LINE (options will not be synchronized)</string>
|
<string name="switch_unembed_options">Do not embed options in LINE (options will not be synchronized)</string>
|
||||||
<string name="switch_remove_voom">Remove the VOOM icon</string>
|
<string name="switch_remove_voom">Remove the VOOM icon</string>
|
||||||
<string name="switch_remove_wallet">Remove the wallet icon</string>
|
<string name="switch_remove_wallet">Remove the wallet icon</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user