mirror of
https://github.com/areteruhiro/LIME-beta-hiro.git
synced 2025-02-15 01:41:36 +09:00
Compare commits
3 Commits
4c8bae7242
...
b0d9f39ab1
Author | SHA1 | Date | |
---|---|---|---|
|
b0d9f39ab1 | ||
|
f112129775 | ||
|
a76ab155ab |
@ -10,7 +10,7 @@ android {
|
||||
minSdk 28
|
||||
targetSdk 35
|
||||
versionCode 11501
|
||||
versionName "1.16.01beta"
|
||||
versionName "1.16.00beta"
|
||||
multiDexEnabled false
|
||||
proguardFiles += 'proguard-rules.pro'
|
||||
buildConfigField 'String', 'HOOK_TARGET_VERSION', '"141910383"'
|
||||
|
@ -1,12 +1,14 @@
|
||||
package io.github.hiro.lime.hooks;
|
||||
|
||||
|
||||
import static android.content.ContentValues.TAG;
|
||||
import static io.github.hiro.lime.Main.limeOptions;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.AndroidAppHelper;
|
||||
import android.app.Application;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
@ -18,8 +20,13 @@ import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
@ -192,16 +199,19 @@ public class ReadChecker implements IHook {
|
||||
return noGroup;
|
||||
}
|
||||
|
||||
|
||||
private void addButton(Activity activity, Context moduleContext) {
|
||||
// ファイルパスを取得
|
||||
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "LimeBackup");
|
||||
File file = new File(dir, "margin_settings.txt");
|
||||
private static final String TAG = "FileHandler";
|
||||
public void addButton(Activity activity, Context moduleContext) {
|
||||
// ファイル取得処理(フォールバック対応)
|
||||
File file = getFile(activity);
|
||||
if (file == null) {
|
||||
Log.e(TAG, "Failed to get a valid file.");
|
||||
return;
|
||||
}
|
||||
|
||||
// デフォルト値
|
||||
float readCheckerHorizontalMarginFactor = 0.5f; // デフォルト値
|
||||
int readCheckerVerticalMarginDp = 100; // デフォルト値
|
||||
float readCheckerSizeDp = 60; // デフォルト値
|
||||
float readCheckerHorizontalMarginFactor = 0.5f;
|
||||
int readCheckerVerticalMarginDp = 100;
|
||||
float readCheckerSizeDp = 60;
|
||||
|
||||
// ファイルの内容を読み込む
|
||||
if (file.exists()) {
|
||||
@ -210,12 +220,16 @@ public class ReadChecker implements IHook {
|
||||
while ((line = reader.readLine()) != null) {
|
||||
String[] parts = line.split("=", 2);
|
||||
if (parts.length == 2) {
|
||||
if (parts[0].trim().equals("Read_checker_horizontalMarginFactor")) {
|
||||
switch (parts[0].trim()) {
|
||||
case "Read_checker_horizontalMarginFactor":
|
||||
readCheckerHorizontalMarginFactor = Float.parseFloat(parts[1].trim());
|
||||
} else if (parts[0].trim().equals("Read_checker_verticalMarginDp")) {
|
||||
break;
|
||||
case "Read_checker_verticalMarginDp":
|
||||
readCheckerVerticalMarginDp = Integer.parseInt(parts[1].trim());
|
||||
} else if (parts[0].trim().equals("chat_read_check_size")) {
|
||||
break;
|
||||
case "chat_read_check_size":
|
||||
readCheckerSizeDp = Float.parseFloat(parts[1].trim());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -223,9 +237,10 @@ public class ReadChecker implements IHook {
|
||||
}
|
||||
}
|
||||
|
||||
// 画像ボタンの設定
|
||||
ImageView imageButton = new ImageView(activity);
|
||||
String imageName = "read_checker.png";
|
||||
File imageFile = new File(dir, imageName);
|
||||
File imageFile = new File(file.getParent(), imageName);
|
||||
|
||||
if (!imageFile.exists()) {
|
||||
try (InputStream in = moduleContext.getResources().openRawResource(
|
||||
@ -245,11 +260,11 @@ public class ReadChecker implements IHook {
|
||||
Drawable drawable = Drawable.createFromPath(imageFile.getAbsolutePath());
|
||||
if (drawable != null) {
|
||||
int sizeInPx = dpToPx(moduleContext, readCheckerSizeDp);
|
||||
drawable = scaleDrawable(drawable, sizeInPx, sizeInPx);
|
||||
imageButton.setImageDrawable(drawable);
|
||||
}
|
||||
}
|
||||
|
||||
// 画像ボタンのレイアウト
|
||||
FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT,
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT
|
||||
@ -260,44 +275,36 @@ public class ReadChecker implements IHook {
|
||||
frameParams.setMargins(horizontalMarginPx, verticalMarginPx, 0, 0);
|
||||
|
||||
imageButton.setLayoutParams(frameParams);
|
||||
|
||||
imageButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
imageButton.setOnClickListener(v -> {
|
||||
if (currentGroupId != null) {
|
||||
showDataForGroupId(activity, currentGroupId, moduleContext);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Delete ボタンを追加
|
||||
if (limeOptions.ReadCheckerChatdataDelete.checked) {
|
||||
Button deleteButton = new Button(activity);
|
||||
deleteButton.setText(moduleContext.getResources().getString(R.string.Delete));
|
||||
deleteButton.setBackgroundColor(Color.RED); // ボタンの背景色を赤に設定
|
||||
deleteButton.setTextColor(Color.WHITE); // ボタンのテキスト色を白に設定
|
||||
deleteButton.setBackgroundColor(Color.RED);
|
||||
deleteButton.setTextColor(Color.WHITE);
|
||||
|
||||
FrameLayout.LayoutParams deleteButtonParams = new FrameLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT,
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
|
||||
// Delete ボタンの位置を画像ボタンの右側に設定
|
||||
deleteButtonParams.setMargins(horizontalMarginPx + dpToPx(moduleContext, readCheckerSizeDp) + 20, verticalMarginPx, 0, 0);
|
||||
deleteButton.setLayoutParams(deleteButtonParams);
|
||||
|
||||
deleteButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
deleteButton.setOnClickListener(v -> {
|
||||
if (currentGroupId != null) {
|
||||
new AlertDialog.Builder(activity)
|
||||
.setTitle(moduleContext.getResources().getString(R.string.check))
|
||||
.setMessage(moduleContext.getResources().getString(R.string.really_delete))
|
||||
.setPositiveButton(moduleContext.getResources().getString(R.string.yes), (confirmDialog, confirmWhich) -> deleteGroupData(currentGroupId, activity, moduleContext))
|
||||
.setPositiveButton(moduleContext.getResources().getString(R.string.yes), (dialog, which) -> deleteGroupData(currentGroupId, activity, moduleContext))
|
||||
.setNegativeButton(moduleContext.getResources().getString(R.string.no), null)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ViewGroup layout = activity.findViewById(android.R.id.content);
|
||||
@ -308,6 +315,50 @@ public class ReadChecker implements IHook {
|
||||
layout.addView(imageButton);
|
||||
}
|
||||
|
||||
private File getFile(Activity activity) {
|
||||
File dir;
|
||||
File file;
|
||||
|
||||
try {
|
||||
dir = new File(activity.getExternalFilesDir(null), "LimeBackup");
|
||||
if (!dir.exists() && !dir.mkdirs()) {
|
||||
throw new IOException("Failed to create directory");
|
||||
}
|
||||
file = new File(dir, "margin_settings.txt");
|
||||
|
||||
if (!file.exists() && !file.createNewFile()) {
|
||||
throw new IOException("Failed to create file");
|
||||
}
|
||||
return file;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "getExternalFilesDir failed, falling back to MediaStore.", e);
|
||||
return getFileFromMediaStore(activity, "LimeBackup/margin_settings.txt");
|
||||
}
|
||||
}
|
||||
|
||||
private File getFileFromMediaStore(Context context, String relativePath) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(MediaStore.Downloads.DISPLAY_NAME, "margin_settings.txt");
|
||||
values.put(MediaStore.Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS + "/LimeBackup");
|
||||
values.put(MediaStore.Downloads.MIME_TYPE, "text/plain");
|
||||
|
||||
Uri fileUri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values);
|
||||
if (fileUri != null) {
|
||||
try (ParcelFileDescriptor pfd = resolver.openFileDescriptor(fileUri, "rw")) {
|
||||
if (pfd != null) {
|
||||
return new File(context.getFilesDir(), "margin_settings.txt");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private int dpToPx(@NonNull Context context, float dp) {
|
||||
float density = context.getResources().getDisplayMetrics().density;
|
||||
return Math.round(dp * density);
|
||||
|
@ -322,21 +322,15 @@ public class UnsentRec implements IHook {
|
||||
}
|
||||
Cursor cursor = db.rawQuery(query, selectionArgs);
|
||||
String result = null;
|
||||
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
do {
|
||||
if (cursor.moveToFirst()) {
|
||||
result = cursor.getString(0);
|
||||
XposedBridge.log("Query Result: " + result); // Log each result found
|
||||
} while (cursor.moveToNext()); // In case there are multiple rows
|
||||
} else {
|
||||
XposedBridge.log("No rows found for query: " + query);
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private int countLinesInFile(File file) {
|
||||
int count = 0;
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)))) {
|
||||
@ -387,16 +381,14 @@ public class UnsentRec implements IHook {
|
||||
String param12 = null;
|
||||
String param22 = null;
|
||||
String operationContent = null;
|
||||
String serverId = null;
|
||||
String talkId = null;
|
||||
String serverId = null; // serverIdをここで宣言
|
||||
|
||||
String[] parts = operation.split(",");
|
||||
for (String part : parts) {
|
||||
part = part.trim();
|
||||
if (part.startsWith("param1:")) {
|
||||
talkId = part.substring("param1:".length()).trim();
|
||||
} else if (part.startsWith("param2:")) {
|
||||
serverId = part.substring("param2:".length()).trim();
|
||||
} else if (part.startsWith("revision:")) {
|
||||
revision = part.substring("revision:".length()).trim();
|
||||
} else if (part.startsWith("createdTime:")) {
|
||||
@ -414,10 +406,23 @@ public class UnsentRec implements IHook {
|
||||
}
|
||||
}
|
||||
|
||||
if (serverId != null && talkId != null) {
|
||||
// 新しいメソッドを呼び出して、メッセージを取り消し済みとして更新
|
||||
// typeがNOTIFIED_DESTROY_MESSAGEの場合のみserverIdを設定
|
||||
if ("NOTIFIED_DESTROY_MESSAGE".equals(type)) {
|
||||
for (String part : parts) {
|
||||
part = part.trim();
|
||||
if (part.startsWith("param2:")) {
|
||||
serverId = part.substring("param2:".length()).trim();
|
||||
break; // param2が見つかったらループを抜ける
|
||||
}
|
||||
}
|
||||
updateMessageAsCanceled(db1, serverId,context,moduleContext);
|
||||
// serverIdを使用した処理をここに追加
|
||||
XposedBridge.log("Server ID for NOTIFIED_DESTROY_MESSAGE: " + serverId);
|
||||
}
|
||||
|
||||
// serverIdとtalkIdが両方ともnullでない場合に処理を行う
|
||||
if (serverId != null && talkId != null) {
|
||||
XposedBridge.log(paramValue + serverId);
|
||||
String content = queryDatabase(db1, "SELECT content FROM chat_history WHERE server_id=?", serverId);
|
||||
String imageCheck = queryDatabase(db1, "SELECT attachement_image FROM chat_history WHERE server_id=?", serverId);
|
||||
String timeEpochStr = queryDatabase(db1, "SELECT created_time FROM chat_history WHERE server_id=?", serverId);
|
||||
@ -459,6 +464,8 @@ public class UnsentRec implements IHook {
|
||||
break;
|
||||
}
|
||||
}
|
||||
XposedBridge.log("S" + serverId);
|
||||
// 新しいメソッドを呼び出して、メッセージを取り消し済みとして更新
|
||||
|
||||
String logEntry = (timeFormatted != null ? timeFormatted : "No Time: ")
|
||||
+ name
|
||||
@ -482,21 +489,16 @@ public class UnsentRec implements IHook {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void canceled_message(XC_LoadPackage.LoadPackageParam loadPackageParam, Context context, SQLiteDatabase db1, SQLiteDatabase db2, Context moduleContext) {
|
||||
Class<?> chatHistoryRequestClass = XposedHelpers.findClass("com.linecorp.line.chat.request.ChatHistoryRequest", loadPackageParam.classLoader);
|
||||
XposedHelpers.findAndHookMethod(chatHistoryRequestClass, "getChatId", new XC_MethodHook() {
|
||||
@Override
|
||||
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
|
||||
String chatId = (String) param.getResult();
|
||||
|
||||
// チャット ID をログに出力
|
||||
XposedBridge.log("Chat ID: " + chatId);
|
||||
String canceledContent = getCanceledContentFromFile(context, moduleContext);
|
||||
|
||||
// チェックボックスの状態を確認
|
||||
if (limeOptions.hide_canceled_message.checked) {
|
||||
XposedBridge.log("hide_canceled_message is checked");
|
||||
|
||||
// content と server_id, chat_id を取得 (複数レコードを想定)
|
||||
Cursor cursor = db1.rawQuery("SELECT content, server_id, chat_id, parameter FROM chat_history WHERE chat_id=?", new String[]{chatId});
|
||||
@ -530,10 +532,9 @@ public class UnsentRec implements IHook {
|
||||
cursor.close();
|
||||
}
|
||||
} else {
|
||||
XposedBridge.log("No rows found for chat_id: " + chatId);
|
||||
|
||||
}
|
||||
} else {
|
||||
XposedBridge.log("hide_canceled_message is NOT checked");
|
||||
|
||||
// hide_canceled_message.checked が false の場合
|
||||
String chatId1 = "/" + (String) param.getResult();
|
||||
@ -578,10 +579,10 @@ public class UnsentRec implements IHook {
|
||||
private void updateMessageAsCanceled(SQLiteDatabase db1, String serverId, Context context, Context moduleContext) {
|
||||
// canceledContent をファイルから取得
|
||||
String canceledContent = getCanceledContentFromFile(context, moduleContext);
|
||||
|
||||
// 既存のメッセージを取得
|
||||
Cursor cursor = db1.rawQuery("SELECT * FROM chat_history WHERE server_id=?", new String[]{serverId});
|
||||
|
||||
|
||||
if (cursor.moveToFirst()) {
|
||||
// カラムの値を取得(null の場合もそのまま代入)
|
||||
String type = cursor.isNull(cursor.getColumnIndex("type")) ? null : cursor.getString(cursor.getColumnIndex("type"));
|
||||
@ -609,6 +610,7 @@ public class UnsentRec implements IHook {
|
||||
// 既存のレコードがあるか確認
|
||||
Cursor existingCursor = db1.rawQuery("SELECT * FROM chat_history WHERE server_id=? AND content=?", new String[]{serverId, chatId});
|
||||
if (!existingCursor.moveToFirst()) {
|
||||
XposedBridge.log(serverId);
|
||||
// 新しいレコードを挿入
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("server_id", serverId);
|
||||
@ -626,11 +628,14 @@ public class UnsentRec implements IHook {
|
||||
values.put("location_phone", locationPhone);
|
||||
if (locationLatitude != null) values.put("location_latitude", locationLatitude);
|
||||
if (locationLongitude != null) values.put("location_longitude", locationLongitude);
|
||||
values.put("attachement_image", attachmentImage);
|
||||
values.put("attachement_image", "0");
|
||||
if (attachmentImageHeight != null) values.put("attachement_image_height", attachmentImageHeight);
|
||||
else values.put("attachement_image_height", (String) null);
|
||||
if (attachmentImageWidth != null) values.put("attachement_image_width", attachmentImageWidth);
|
||||
else values.put("attachement_image_width", (String) null);
|
||||
if (attachmentImageSize != null) values.put("attachement_image_size", attachmentImageSize);
|
||||
values.put("attachement_type", attachmentType);
|
||||
else values.put("attachement_image_size", (String) null);
|
||||
values.put("attachement_type", "0");
|
||||
values.put("attachement_local_uri", attachmentLocalUri);
|
||||
values.put("parameter", "LIMEsUnsend"); // ここを修正
|
||||
values.put("chunks", chunks);
|
||||
|
Loading…
Reference in New Issue
Block a user