Compare commits

...
Author SHA1 Message Date
gdlbo 5dd616685d Decrypt 2022-05-06 14:50:02 +03:00
gdlbo aff99be92d Fixes 2022-05-06 14:05:23 +03:00
gdlbo c255f1e498 Undelete feature + fixes 2022-05-06 13:43:42 +03:00
gdlbo 70342daf07 Merge branch 'master' of https://github.com/vtosters/lite 2022-05-06 01:58:35 +03:00
gdlbo f95672e57d Encryption + Undelete code base 2022-05-06 01:57:33 +03:00
gdlbo 8f5da42df4 color fixes 2022-05-04 16:41:59 +03:00
gdlbo 4022903069 Fixed crash 2022-05-04 14:23:25 +03:00
gdlbo 4600c185e4 Added proxy user/pass auth 2022-05-04 13:12:39 +03:00
gdlbo 30e8ec0038 Update README.md 2022-05-03 23:45:37 +03:00
45 changed files with 1148 additions and 107 deletions
+4 -4
View File
@@ -8,14 +8,14 @@ VTosters Lite - это модифицированный клиент (деком
Стабильные сборки находятся в [Releases](https://github.com/vtosters/lite/releases)
## Откладка
## Отладка приложения
Для откладки с помощью Android Studio необходимо пройти в `/smali/AndroidManifest.xml`
Для отладки с помощью Android Studio необходимо пройти в `/smali/AndroidManifest.xml`
```
android:debuggable="false" -> android:debuggable="true"
```
Для дополнительной откладки ответов, доп логов и подмены данных для дебаг приложения необходимо включить **Режим разработчика**
Для дополнительной отладки ответов, доп логов и подмены данных для дебаг приложения необходимо включить **Режим разработчика**
```
Настройки -> Для разработчиков -> Режим разработчика
```
@@ -92,4 +92,4 @@ android:debuggable="false" -> android:debuggable="true"
build.bat
```
![](https://cdn.discordapp.com/attachments/762063967979175946/961682299366309928/unknown.png)
![](https://cdn.discordapp.com/attachments/762063967979175946/961682299366309928/unknown.png)
@@ -0,0 +1,116 @@
package ru.vtosters.lite.encryption;
import android.util.Log;
import android.util.Pair;
import com.vk.im.engine.models.messages.Msg;
import com.vk.im.engine.models.messages.MsgFromUser;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import ru.vtosters.lite.encryption.base.IMProcessor;
import ru.vtosters.lite.encryption.processors.BeeCryptProcessor;
import ru.vtosters.lite.encryption.processors.DefaultCoffeeProcessor;
import ru.vtosters.lite.encryption.processors.DonateCoffeeProcessor;
import ru.vtosters.lite.encryption.processors.MP3InvisibleProcessor;
import ru.vtosters.lite.encryption.processors.VTostersAESProcessor;
import ru.vtosters.lite.encryption.processors.VTostersProcessor;
public class EncryptProvider {
public static List<IMProcessor> processors = new ArrayList<>();
public static IMProcessor getProcessorFor(int peerId) {
IMProcessor enabled = null;
for (IMProcessor processor: EncryptProvider.processors) {
if (processor.isUsedToEncrypt(peerId)) {
enabled = processor;
}
}
return enabled;
}
public static String getBody(MsgFromUser msg) {
return msg.E();
}
public static int getPeerId(Msg msg) {
return msg.b();
}
// This will run through EVERY single processor available.
public static String decryptMessage(MsgFromUser msg) {
return decryptMessage(getBody(msg), getPeerId(msg));
}
public static String decryptMessage(String msgBody, int peer) {
try {
for (IMProcessor processor : processors) {
if ((processor.isUsed() || !processor.isPublic()) && processor.isEncrypted(msgBody) && (processor.isPublic() || getKeyForProcessor(processor, peer) != null))
return "\uD83D\uDD12 " + processor.decode(msgBody, getKeyForProcessor(processor, peer));
}
} catch (Exception e) {
e.printStackTrace();
}
return msgBody;
}
private static byte[] getKeyForProcessor(IMProcessor processor, int peer) {
if (processor.isPublic()) return null;
String keyString = processor.getEncryptionKeyFor(peer);
if (keyString == null) return null;
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(keyString.getBytes());
byte[] key = new byte[16];
System.arraycopy(hash, 0, key, 0, key.length);
return key;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return keyString.getBytes();
}
// This will use only the processor which was chosen in chat menu [that's why ID is needed, bruh]
public static String encryptMessage(MsgFromUser msg) {
String msgBody = getBody(msg);
Log.d("EncryptProvider", "encryptMessage: msg = " + msg.toString());
Log.d("EncryptProvider", "encryptMessage: body = " + msgBody);
Log.d("EncryptProvider", "encryptMessage: peerId = " + getPeerId(msg));
for (IMProcessor processor: processors) {
int peer = getPeerId(msg);
if (processor.isUsedToEncrypt(peer)) {
return processor.encode(msgBody, getKeyForProcessor(processor, peer));
}
}
return msgBody;
}
// For rendering UI
public static List<Pair<String, String>> getUserVisibleEncoders() {
List<Pair<String, String>> theList = new ArrayList<>();
for (IMProcessor processor: processors) {
if (processor.isPublic()) theList.add(new Pair<>("VT_IMDecode_"+processor.getPrefKey(), processor.getUIName()));
}
return theList;
}
static {
processors.add(new VTostersProcessor());
processors.add(new VTostersAESProcessor());
processors.add(new DefaultCoffeeProcessor());
processors.add(new DonateCoffeeProcessor());
processors.add(new BeeCryptProcessor());
processors.add(new MP3InvisibleProcessor());
}
}
@@ -0,0 +1,78 @@
package ru.vtosters.lite.encryption.base;
import static ru.vtosters.lite.utils.Preferences.BooleanFalse;
import static ru.vtosters.lite.utils.Preferences.BooleanTrue;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import ru.vtosters.lite.utils.Globals;
public abstract class IMProcessor {
// By default it checks start and end tag.
public boolean isEncrypted(String source) {
//Log.d("IMProcessor", "Checking if encrypted: "+source+" / "+getUIName());
return source.startsWith(startTag()) && source.endsWith(endTag());
}
// Key can be null - if it's a public processor
@NonNull protected abstract String encodeInternal(@NonNull String source, @Nullable byte[] key);
@NonNull protected abstract String decodeInternal(@NonNull String source, @Nullable byte[] key);
// Automatically removes tags. Magic!
@NonNull
public String encode(@NonNull String source, @Nullable byte[] key) {
//Log.d("IMProcessor", "Encoding "+source);
return startTag() + encodeInternal(source, key) + endTag();
}
@NonNull
public String decode(@NonNull String source, @Nullable byte[] key) {
//Log.d("IMProcessor", "Decoding");
return decodeInternal(source.substring(startTag().length(), source.length() - endTag().length()), key);
}
// Public - no key required.
public boolean isPublic() {
return true;
}
// UI thing
@NonNull abstract public String getUIName();
@NonNull abstract public String getPrefKey();
@NonNull public String startTag() {
return "";
}
@NonNull public String endTag() {
return "";
}
public boolean isUsed() {
//Log.d("IMProcessor", "Checking if decoded with "+getUIName());
return BooleanTrue("VT_IMDecode_"+getPrefKey());
}
public boolean isUsedToEncrypt(int id) {
//Log.d("IMProcessor", "Checking if "+id+" is ready to be encrypted with "+getUIName());
return BooleanFalse("VT_IMEncode_"+getPrefKey()+"_"+id);
}
public void enableEncryptFor(int id) {
Globals.getPrefs().edit().putBoolean("VT_IMEncode_"+getPrefKey()+"_"+id, true).apply();
}
public void disableEncryptFor(int id) {
Globals.getPrefs().edit().putBoolean("VT_IMEncode_"+getPrefKey()+"_"+id, false).apply();
}
public void setEncryptionKeyFor(int id, @Nullable String key) {
if (key == null || key.isEmpty()) key = "VTAesDefault";
Globals.getPrefs().edit().putString("VT_IMEncodeKey_"+getPrefKey()+"_"+id, key).apply();
}
@Nullable
public String getEncryptionKeyFor(int id) {
return Globals.getPrefs().getString("VT_IMEncodeKey_"+getPrefKey()+"_"+id, null);
}
}
@@ -0,0 +1,75 @@
package ru.vtosters.lite.encryption.processors;
import android.util.Base64;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.nio.charset.StandardCharsets;
import ru.vtosters.lite.encryption.base.IMProcessor;
public class BeeCryptProcessor extends IMProcessor {
private static final String BC_CHARSET = "жъЖЪ";
@NonNull
@Override
protected String encodeInternal(@NonNull String source, @Nullable byte[] key) {
try {
String a = Base64.encodeToString(source.getBytes(StandardCharsets.UTF_8), 2);
StringBuilder res = new StringBuilder();
for (int i = 0; i < a.length(); i++) {
StringBuilder bintxt = new StringBuilder();
int c = a.charAt(i);
for (int j = 0; j < 4; j++) {
bintxt.insert(0, BC_CHARSET.charAt(c % 4));
c /= 4;
}
res.append(bintxt);
}
return res.toString();
} catch (java.lang.Exception e) {
e.printStackTrace();
return source;
}
}
@Override
public boolean isEncrypted(String source) {
return source.matches("[жъЖЪ]{16,}");
}
@NonNull
@Override
protected String decodeInternal(@NonNull String source, @Nullable byte[] key) {
StringBuilder b64 = new StringBuilder();
int i = 0;
while (i < source.length() - 3) {
try {
String bintxt = source.substring(i, i + 4);
int c = 0;
for (int j = 0; j < 4; j++) {
c = (c * 4) + Math.max(0, BC_CHARSET.indexOf(bintxt.charAt(j)));
}
b64.append((char) c);
i += 4;
} catch (java.lang.Exception e) {
e.printStackTrace();
return source;
}
}
return new String(Base64.decode(b64.toString(), 2), StandardCharsets.UTF_8);
}
@NonNull
@Override
public String getUIName() {
return "MP3 [beecrypt]";
}
@NonNull
@Override
public String getPrefKey() {
return "mp3_bc";
}
}
@@ -0,0 +1,103 @@
package ru.vtosters.lite.encryption.processors;
import android.util.Base64;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import ru.vtosters.lite.encryption.base.IMProcessor;
public class DefaultCoffeeProcessor extends IMProcessor {
private final static String KEY = "stupidUsersMustD";
private static Cipher dCipher, eCipher;
static {
try {
SecretKeySpec key = new SecretKeySpec(KEY.getBytes(), "AES");
dCipher = Cipher.getInstance("AES");
dCipher.init(Cipher.DECRYPT_MODE, key);
eCipher = Cipher.getInstance("AES");
eCipher.init(Cipher.ENCRYPT_MODE, key);
} catch (Exception e) {
e.printStackTrace();
}
}
private String toHex(String text) {
char[] chars = text.toCharArray();
StringBuilder str = new StringBuilder();
for (char aChar : chars) {
String s = Integer.toHexString(aChar);
if (s.length() < 2) s = "0" + s;
str.append(s.toUpperCase()).append(" ");
}
String string = str.toString();
return string.substring(0, string.length()-1);
}
private String fromHex(String text) {
text = text.replace(" ", "");
char[] chars = text.toCharArray();
char[] chars2 = new char[chars.length/2];
for (int i = 0; i < chars.length; i+=2) {
String c = String.valueOf(chars[i]) + chars[i + 1];
chars2[i/2] = (char) Integer.parseInt(c, 16);
}
return new String(chars2);
}
@NonNull
@Override
protected String encodeInternal(@NonNull String source, @Nullable byte[] key) {
try {
return toHex(Base64.encodeToString(eCipher.doFinal(source.getBytes()), 0));
} catch (Exception e) {
e.printStackTrace();
}
return source;
}
@NonNull
@Override
protected String decodeInternal(@NonNull String source, @Nullable byte[] key) {
try {
return new String(dCipher.doFinal(Base64.decode(fromHex(source), 0)));
} catch (Exception e) {
e.printStackTrace();
}
return source;
}
@Override
@NonNull
public String startTag() {
return "VK CO FF EE ";
}
@Override
@NonNull
public String endTag() {
return " VK CO FF EE";
}
@NonNull
@Override
public String getUIName() {
return "VK Coffee [default]";
}
@NonNull
@Override
public String getPrefKey() {
return "coffee_default";
}
}
@@ -0,0 +1,29 @@
package ru.vtosters.lite.encryption.processors;
import androidx.annotation.NonNull;
public class DonateCoffeeProcessor extends DefaultCoffeeProcessor {
@Override
@NonNull
public String startTag() {
return "II ";
}
@Override
@NonNull
public String endTag() {
return " II";
}
@NonNull
@Override
public String getUIName() {
return "VK Coffee [hidden]";
}
@NonNull
@Override
public String getPrefKey() {
return "coffee_donate";
}
}
@@ -0,0 +1,79 @@
package ru.vtosters.lite.encryption.processors;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.nio.charset.StandardCharsets;
import ru.vtosters.lite.encryption.base.IMProcessor;
public class MP3InvisibleProcessor extends IMProcessor {
@NonNull
@Override
protected String encodeInternal(@NonNull String source, @Nullable byte[] key) {
try {
byte[] bytes = source.getBytes(StandardCharsets.UTF_8);
java.lang.String[] plainText = new String[bytes.length];
for (int i = 0; i < plainText.length; i++) {
plainText[i] = toStr(bytes[i] & 255, " ​‌‏ ");
}
return "  " + TextUtils.join(" ", plainText);
} catch (java.lang.Exception e) {
e.printStackTrace();
return source;
}
}
@NonNull
@Override
protected String decodeInternal(@NonNull String source, @Nullable byte[] key) {
try {
java.lang.String[] t = source.replaceAll("^" + "  ", "").split(" ");
byte[] plainText = new byte[t.length];
for (int i = 0; i < plainText.length; i++) {
plainText[i] = (byte) toNum(t[i], " ​‌‏ ");
}
return new String(plainText, StandardCharsets.UTF_8);
} catch (java.lang.Exception e) {
e.printStackTrace();
return source;
}
}
private static String toStr(int a, String cc) {
StringBuilder s = new StringBuilder();
while (a > 0) {
s.insert(0, cc.charAt(a % cc.length()));
a /= cc.length();
}
return s.toString();
}
private static int toNum(String a, String cc) {
int n = 0;
for (int i = 0; i < a.length(); i++) {
int start = (a.length() - i) - 1;
n = (int) (((double) n) + (((double) cc.indexOf(a.substring(start, start + 1))) * Math.pow(cc.length(), i)));
}
return n;
}
@Override
public boolean isEncrypted(String source) {
return source.matches("^" + "  " + "([" + " ​‌‏ " + "\\s]*)");
}
@NonNull
@Override
public String getUIName() {
return "MP3 [invisible]";
}
@NonNull
@Override
public String getPrefKey() {
return "mp3";
}
}
@@ -0,0 +1,130 @@
package ru.vtosters.lite.encryption.processors;
import android.util.Base64;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import ru.vtosters.lite.encryption.base.IMProcessor;
import ru.vtosters.lite.utils.Globals;
public class VTostersAESProcessor extends IMProcessor {
private final static String CIPHER_INSTANCE = "AES/CBC/PKCS7Padding";
private final static String KEY_METHOD = "AES";
private HashMap<byte[], Cipher> decodeMap = new HashMap<>(), encodeMap = new HashMap<>();
public void free(byte[] key) {
decodeMap.remove(key);
encodeMap.remove(key);
}
@NonNull
private Cipher wrapEncoder(byte[] key) throws InvalidAlgorithmParameterException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException {
if (encodeMap.containsKey(key)) return encodeMap.get(key);
Triple<Cipher, SecretKeySpec, IvParameterSpec> encodeCipher = getBaseCipher(key);
encodeCipher.first.init(Cipher.ENCRYPT_MODE, encodeCipher.second, encodeCipher.third);
encodeMap.put(key, encodeCipher.first);
return encodeCipher.first;
}
@NonNull
private Cipher wrapDecoder(byte[] key) throws InvalidAlgorithmParameterException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException {
if (decodeMap.containsKey(key)) return decodeMap.get(key);
Triple<Cipher, SecretKeySpec, IvParameterSpec> decodeCipher = getBaseCipher(key);
decodeCipher.first.init(Cipher.DECRYPT_MODE, decodeCipher.second, decodeCipher.third);
decodeMap.put(key, decodeCipher.first);
return decodeCipher.first;
}
@NonNull
private Triple<Cipher, SecretKeySpec, IvParameterSpec> getBaseCipher(byte[] key) throws NoSuchPaddingException, NoSuchAlgorithmException {
byte[] off = new byte[16];
System.arraycopy(key, 0, off, 0, off.length);
return new Triple<>(Cipher.getInstance(CIPHER_INSTANCE), new SecretKeySpec(key, KEY_METHOD), new IvParameterSpec(off));
}
@NonNull
@Override
protected String encodeInternal(@NonNull String source, @Nullable byte[] key) {
try {
return Base64.encodeToString(wrapEncoder(key).doFinal(source.getBytes(StandardCharsets.UTF_8)), Base64.DEFAULT);
} catch (Exception e) {
e.printStackTrace();
return source;
}
}
@NonNull
@Override
protected String decodeInternal(@NonNull String source, @Nullable byte[] key) {
try {
return new String(wrapDecoder(key).doFinal(Base64.decode(source, Base64.DEFAULT)), StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
return source;
}
}
@Override
public boolean isPublic() {
return false;
}
@NonNull
@Override
public String startTag() {
return "VT0ST3RS [AES] ";
}
@NonNull
@Override
public String endTag() {
return " VT0ST3RS [AES]";
}
@NonNull
@Override
public String getUIName() {
return "VTosters [AES]";
}
@NonNull
@Override
public String getPrefKey() {
return "vtaes";
}
@Nullable
@Override
public String getEncryptionKeyFor(int id) {
return Globals.getPrefs().getString("VT_IMEncodeKey_"+getPrefKey()+"_"+id, "VTAesDefault");
}
public static class Triple<F, S, T> {
public final F first;
public final S second;
public final T third;
public Triple(F first, S second, T third) {
this.first = first;
this.second = second;
this.third = third;
}
}
}
@@ -0,0 +1,46 @@
package ru.vtosters.lite.encryption.processors;
import android.util.Base64;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import ru.vtosters.lite.encryption.base.IMProcessor;
public class VTostersProcessor extends IMProcessor {
@NonNull
@Override
protected String encodeInternal(@NonNull String source, @Nullable byte[] key) {
return Base64.encodeToString(source.getBytes(), Base64.DEFAULT);
}
@NonNull
@Override
protected String decodeInternal(@NonNull String source, @Nullable byte[] key) {
return new String(Base64.decode(source, Base64.DEFAULT));
}
@Override
@NonNull
public String startTag() {
return "VT0ST3RS ";
}
@Override
@NonNull
public String endTag() {
return " VT0ST3RS";
}
@NonNull
@Override
public String getUIName() {
return "VTosters Classique [Base64]";
}
@NonNull
@Override
public String getPrefKey() {
return "vt64";
}
}
@@ -74,6 +74,8 @@ public class OtherFragment extends MaterialPreferenceToolbarFragment {
@Override // android.support.v7.preference.Preference.c
public boolean a(Preference preference) {
SharedPreferences prefs = getContext().getSharedPreferences("stickers", Context.MODE_PRIVATE);
prefs.edit().clear().commit();
VKImageLoader.b();
ImEngineProvider.a().h();
AudioMessageUtils.j();
@@ -1,12 +1,15 @@
package ru.vtosters.lite.ui.fragments.multiaccount;
import static ru.vtosters.lite.utils.Globals.convertDpToPixel;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.Globals.getResources;
import static ru.vtosters.lite.utils.Globals.isNetworkConnected;
import static ru.vtosters.lite.utils.Globals.restartApplication;
import static ru.vtosters.lite.utils.Themes.getTextAttr;
import static ru.vtosters.lite.utils.Themes.recolorDrawable;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.RecyclerView;
@@ -127,6 +130,8 @@ public class MultiAccountAdapter extends RecyclerView.a<MultiAccountAdapter.Mult
VKAccount b = VKAccountManager.b();
PushSubscriber.a.a(b.b(), b.c());
AppContextHolder.a.getSharedPreferences("gcm", 0).edit().clear().apply();
SharedPreferences prefs = getContext().getSharedPreferences("stickers", Context.MODE_PRIVATE);
prefs.edit().clear().commit();
restartApplication();
});
Drawable drawable = recolorDrawable(getResources().getDrawable(R.drawable.ic_list_add));
@@ -143,6 +148,8 @@ public class MultiAccountAdapter extends RecyclerView.a<MultiAccountAdapter.Mult
VKAccount b = VKAccountManager.b();
PushSubscriber.a.a(b.b(), b.c());
AppContextHolder.a.getSharedPreferences("gcm", 0).edit().clear().apply();
SharedPreferences prefs = getContext().getSharedPreferences("stickers", Context.MODE_PRIVATE);
prefs.edit().clear().commit();
restartApplication();
});
@@ -164,6 +171,8 @@ public class MultiAccountAdapter extends RecyclerView.a<MultiAccountAdapter.Mult
VKAccount b = VKAccountManager.b();
PushSubscriber.a.a(b.b(), b.c());
AppContextHolder.a.getSharedPreferences("gcm", 0).edit().clear().apply();
SharedPreferences prefs = getContext().getSharedPreferences("stickers", Context.MODE_PRIVATE);
prefs.edit().clear().commit();
restartApplication();
});
}
@@ -1,7 +1,9 @@
package ru.vtosters.lite.utils;
import static ru.vtosters.lite.utils.Globals.*;
import static ru.vtosters.lite.utils.Preferences.*;
import static ru.vtosters.lite.utils.Globals.getApplicationName;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.Preferences.VERSIONNAME;
import static ru.vtosters.lite.utils.Preferences.oldabout;
import android.content.Context;
@@ -0,0 +1,172 @@
package ru.vtosters.lite.utils;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.Globals.getPreferences;
import static ru.vtosters.lite.utils.Preferences.BooleanFalse;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteOpenHelper;
import android.text.TextUtils;
import com.vk.im.engine.events.OnMsgUpdateEvent;
import com.vk.im.engine.internal.longpoll.a.MsgDeleteLpTask;
import com.vk.im.engine.internal.storage.CacheEnvironment;
import com.vk.im.engine.models.messages.Msg;
import com.vk.im.engine.models.messages.MsgFromUser;
import com.vk.im.engine.models.messages.NestedMsg;
import com.vk.libsqliteext.CustomSqliteExtensions;
import org.sqlite.database.sqlite.SQLiteDatabase;
import java.util.ArrayList;
import java.util.List;
import ru.vtosters.lite.encryption.EncryptProvider;
public class DeletedMessagesHandler {
private static List<Integer> sDeletedMessagesList = new ArrayList<>();
private static SQLiteDatabase sVKSQLiteDatabase;
private static int sBodyIndex = -1;
private static DeletedMessagesDBHelper sVTDatabase;
public static void reloadMessagesList() {
if (sVTDatabase == null) {
sVTDatabase = new DeletedMessagesDBHelper();
}
sDeletedMessagesList = new ArrayList<>(sVTDatabase.loadAllMessages());
}
public static void grabVKDatabase(CacheEnvironment storageEnvironment) {
sVKSQLiteDatabase = storageEnvironment.b();
}
public static boolean hook() {
return BooleanFalse("undeletemsg");
}
public static void setBodyDBParser(Msg msg) {
if (!(msg instanceof MsgFromUser)) return;
for (Integer integer : sDeletedMessagesList) {
MsgFromUser msgFromUser = (MsgFromUser) msg;
checkForNestedMsg(msgFromUser.g);
if (integer == msg.d) {
editTextOfMsg((MsgFromUser) msg);
break;
}
}
}
private static void checkForNestedMsg(List<NestedMsg> nestedMsgs) {
for (NestedMsg nestedMsg : nestedMsgs) {
if (!nestedMsg.i.isEmpty()) checkForNestedMsg(nestedMsg.i);
nestedMsg.b(EncryptProvider.decryptMessage(nestedMsg.E(), nestedMsg.h().c));
}
}
private static void editTextOfMsg(MsgFromUser msgFromUser) {
if (!msgFromUser.e.startsWith(getPreifxUndelete())) {
msgFromUser.e = getPreifxUndelete() + EncryptProvider.decryptMessage(msgFromUser);
}
}
private static String getPreifxUndelete() {
String string = getPreferences().getString("undeletemsg_prefix", "");
if (string.isEmpty()) {
return "[Удалено] ";
}
if (string.equals("icon")) {
return "\uD83D\uDDD1 ";
}
if (string.equals("icon2")) {
return "❌ ";
}
return "[Удалено] ";
}
public static void updateDialog(MsgDeleteLpTask msgDeleteLpTask) {
Cursor c = getMessageFromDatabaseById(msgDeleteLpTask.c);
if (c == null) return;
int localId = c.getInt(c.getColumnIndex("local_id"));
String str = DeletedMessagesHandler.class.getSimpleName();
msgDeleteLpTask.a.a(str, new OnMsgUpdateEvent(str, msgDeleteLpTask.b, localId));
}
public static void hookDeletedMessageId(MsgDeleteLpTask msgDeleteLpTask) {
if (!hook()) return;
int messageId = msgDeleteLpTask.c;
Cursor c = getMessageFromDatabaseById(messageId);
if (c == null) return;
if (sBodyIndex == -1) sBodyIndex = c.getColumnIndex("body");
if (TextUtils.isEmpty(c.getString(sBodyIndex))) {
deleteMessageFromDB(messageId);
return;
}
sDeletedMessagesList.add(messageId);
sVTDatabase.saveDeletedMessage(messageId);
}
public static Cursor getMessageFromDatabaseById(int messageId) {
String query = "SELECT * FROM messages WHERE vk_id = " + messageId;
Cursor c = CustomSqliteExtensions.a(sVKSQLiteDatabase, query);
if (!c.moveToFirst()) return null;
return c;
}
public static void deleteMessageFromDB(int messageId) {
sVKSQLiteDatabase.execSQL("DELETE FROM messages WHERE vk_id = " + messageId);
}
public static class DeletedMessagesDBHelper extends SQLiteOpenHelper {
public DeletedMessagesDBHelper() {
super(getContext(), "deleted_msgs", null, 1);
}
@Override
public void onCreate(android.database.sqlite.SQLiteDatabase db) {
db.execSQL("create table deleted_msgs (id integer primary key, msgId integer)");
}
@Override
public void onUpgrade(android.database.sqlite.SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void saveDeletedMessage(int msgId) {
android.database.sqlite.SQLiteDatabase sqLiteDatabase = getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("msgId", msgId);
sqLiteDatabase.insert("deleted_msgs", null, contentValues);
sqLiteDatabase.close();
}
public List<Integer> loadAllMessages() {
List<Integer> msgIdsList = new ArrayList<>();
Cursor cursor = getReadableDatabase().query("deleted_msgs", null, null, null, null, null, null);
if (cursor.moveToFirst()) {
int msgIdIndex = cursor.getColumnIndex("msgId");
do {
msgIdsList.add(cursor.getInt(msgIdIndex));
} while (cursor.moveToNext());
cursor.close();
}
return msgIdsList;
}
}
}
@@ -2,7 +2,7 @@ package ru.vtosters.lite.utils;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.Globals.isEmpty;
import static ru.vtosters.lite.utils.Preferences.*;
import static ru.vtosters.lite.utils.Preferences.isEnableExternalOpening;
import android.app.AlertDialog;
import android.content.Context;
@@ -34,6 +34,13 @@ import java.util.Locale;
public class Globals {
private static final List<Activity> activities = new ArrayList<>();
static SharedPreferences prefs = getContext().getSharedPreferences("com.vtosters.lite_preferences", Context.MODE_PRIVATE);
public static SharedPreferences getPrefs() {
if (prefs == null) prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
return prefs;
}
// Current UserId
public static int getUserId() {
return VKAccountManager.b().a();
@@ -207,6 +214,11 @@ public class Globals {
});
}
public static Activity getCurrentActivity() {
if (activities.size() == 0) return null;
else return activities.get(0);
}
public static String getApplicationName() {
return getContext().getApplicationInfo().loadLabel(getContext().getPackageManager()).toString();
}
@@ -1,9 +1,13 @@
package ru.vtosters.lite.utils;
import static ru.vtosters.lite.ui.fragments.multiaccount.MultiAccountManager.migrate;
import static ru.vtosters.lite.utils.Globals.*;
import static ru.vtosters.lite.utils.Newsfeed.*;
import static ru.vtosters.lite.utils.Proxy.*;
import static ru.vtosters.lite.utils.DeletedMessagesHandler.reloadMessagesList;
import static ru.vtosters.lite.utils.Globals.fixGapps;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.Globals.getPreferences;
import static ru.vtosters.lite.utils.Globals.registerActivities;
import static ru.vtosters.lite.utils.Newsfeed.setupFilters;
import static ru.vtosters.lite.utils.Proxy.setProxy;
import android.app.Application;
import android.content.Context;
@@ -24,6 +28,7 @@ public class Preferences {
fixGapps();
setProxy();
migrate();
reloadMessagesList();
registerActivities(application);
}
@@ -1,5 +1,6 @@
package ru.vtosters.lite.utils;
import static java.lang.System.*;
import static ru.vtosters.lite.utils.Globals.*;
import static ru.vtosters.lite.utils.Preferences.*;
@@ -81,54 +82,90 @@ public class Proxy {
}
public static void setProxy() {
Properties properties = getProperties();
switch (getPreferences().getString("proxy", "")) {
case "zaborona":
Properties properties = System.getProperties();
properties.setProperty("socksProxyHost", "socks.zaboronahelp.pp.ua");
properties.setProperty("socksProxyPort", "1488");
System.clearProperty("https.proxyHost");
System.clearProperty("https.proxyPort");
System.clearProperty("http.proxyHost");
System.clearProperty("http.proxyPort");
clearProperty("java.net.socks.username");
clearProperty("java.net.socks.password");
resetProxySocks();
break;
case "socks":
Properties properties2 = System.getProperties();
properties2.setProperty("socksProxyHost", proxyHostSocks());
properties2.setProperty("socksProxyPort", proxyPortSocks());
System.clearProperty("https.proxyHost");
System.clearProperty("https.proxyPort");
System.clearProperty("http.proxyHost");
System.clearProperty("http.proxyPort");
properties.setProperty("socksProxyHost", proxyHostSocks());
properties.setProperty("socksProxyPort", proxyPortSocks());
properties.setProperty("java.net.socks.username", proxyUserSocks());
properties.setProperty("java.net.socks.password", proxyPassSocks());
resetProxySocks();
break;
case "http":
Properties properties3 = System.getProperties();
properties3.setProperty("http.proxyHost", proxyHostHTTP());
properties3.setProperty("http.proxyPort", proxyPortHTTP());
System.clearProperty("socksProxyHost");
System.clearProperty("socksPortHost");
System.clearProperty("https.proxyHost");
System.clearProperty("https.proxyPort");
properties.setProperty("http.proxyHost", proxyHostHTTP());
properties.setProperty("http.proxyPort", proxyPortHTTP());
properties.setProperty("http.proxyUser", proxyUserHTTP());
properties.setProperty("http.proxyPassword", proxyPassHTTP());
resetProxyHttp();
break;
case "https":
Properties properties4 = System.getProperties();
properties4.setProperty("https.proxyHost", proxyHostHTTPS());
properties4.setProperty("https.proxyPort", proxyPortHTTPS());
System.clearProperty("socksProxyHost");
System.clearProperty("socksPortHost");
System.clearProperty("http.proxyHost");
System.clearProperty("http.proxyPort");
properties.setProperty("https.proxyHost", proxyHostHTTPS());
properties.setProperty("https.proxyPort", proxyPortHTTPS());
properties.setProperty("https.proxyUser", proxyUserHTTPS());
properties.setProperty("https.proxyPassword", proxyPassHTTPS());
resetProxyHttps();
break;
default:
System.clearProperty("socksProxyHost");
System.clearProperty("socksPortHost");
System.clearProperty("https.proxyHost");
System.clearProperty("https.proxyPort");
System.clearProperty("http.proxyHost");
System.clearProperty("http.proxyPort");
resetProxy();
break;
}
}
public static void resetProxy() {
clearProperty("https.proxyHost");
clearProperty("https.proxyPort");
clearProperty("https.proxyUser");
clearProperty("https.proxyPassword");
clearProperty("http.proxyHost");
clearProperty("http.proxyPort");
clearProperty("http.proxyUser");
clearProperty("http.proxyPassword");
clearProperty("socksProxyHost");
clearProperty("socksPortHost");
clearProperty("java.net.socks.username");
clearProperty("java.net.socks.password");
}
public static void resetProxySocks() {
clearProperty("https.proxyHost");
clearProperty("https.proxyPort");
clearProperty("https.proxyUser");
clearProperty("https.proxyPassword");
clearProperty("http.proxyHost");
clearProperty("http.proxyPort");
clearProperty("http.proxyUser");
clearProperty("http.proxyPassword");
}
public static void resetProxyHttp() {
clearProperty("https.proxyHost");
clearProperty("https.proxyPort");
clearProperty("https.proxyUser");
clearProperty("https.proxyPassword");
clearProperty("socksProxyHost");
clearProperty("socksPortHost");
clearProperty("java.net.socks.username");
clearProperty("java.net.socks.password");
}
public static void resetProxyHttps() {
clearProperty("http.proxyHost");
clearProperty("http.proxyPort");
clearProperty("http.proxyUser");
clearProperty("http.proxyPassword");
clearProperty("socksProxyHost");
clearProperty("socksPortHost");
clearProperty("java.net.socks.username");
clearProperty("java.net.socks.password");
}
public static String proxyHostHTTP() {
String string = getPreferences().getString("proxyHostHTTP", "");
return string.isEmpty() ? "192.168.0.1" : string;
@@ -159,6 +196,36 @@ public class Proxy {
return string.isEmpty() ? "8888" : string;
}
public static String proxyUserHTTP() {
String string = getPreferences().getString("proxyUserHTTP", "");
return string.isEmpty() ? "" : string;
}
public static String proxyUserHTTPS() {
String string = getPreferences().getString("proxyUserHTTPS", "");
return string.isEmpty() ? "" : string;
}
public static String proxyUserSocks() {
String string = getPreferences().getString("proxyUserSocks", "");
return string.isEmpty() ? "" : string;
}
public static String proxyPassHTTP() {
String string = getPreferences().getString("proxyPassHTTP", "");
return string.isEmpty() ? "" : string;
}
public static String proxyPassHTTPS() {
String string = getPreferences().getString("proxyPassHTTPS", "");
return string.isEmpty() ? "" : string;
}
public static String proxyPassSocks() {
String string = getPreferences().getString("proxyPassSocks", "");
return string.isEmpty() ? "" : string;
}
public static boolean proxy() {
return getPreferences().getString("proxy", "").equals("apiproxy");
}
@@ -1,9 +1,13 @@
package ru.vtosters.lite.utils;
import static ru.vtosters.lite.utils.About.*;
import static ru.vtosters.lite.utils.Globals.*;
import static ru.vtosters.lite.utils.Preferences.*;
import static ru.vtosters.lite.utils.Proxy.*;
import static ru.vtosters.lite.utils.About.getBuildNumber;
import static ru.vtosters.lite.utils.Globals.getPreferences;
import static ru.vtosters.lite.utils.Globals.getUserSecret;
import static ru.vtosters.lite.utils.Globals.getUserToken;
import static ru.vtosters.lite.utils.Preferences.dev;
import static ru.vtosters.lite.utils.Preferences.getLocale;
import static ru.vtosters.lite.utils.Preferences.vksans;
import static ru.vtosters.lite.utils.Proxy.proxy;
import com.vk.core.ui.themes.VKThemeHelper;
@@ -1,7 +1,11 @@
package ru.vtosters.lite.utils;
import static ru.vtosters.lite.utils.Globals.*;
import static ru.vtosters.lite.utils.Preferences.*;
import static ru.vtosters.lite.utils.Globals.getContext;
import static ru.vtosters.lite.utils.Globals.getPreferences;
import static ru.vtosters.lite.utils.Preferences.color_grishka;
import static ru.vtosters.lite.utils.Preferences.isBGStickersEnabled;
import static ru.vtosters.lite.utils.Preferences.navbar;
import static ru.vtosters.lite.utils.Preferences.vksans;
import android.content.Context;
import android.content.res.ColorStateList;
+1 -1
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple android:color="@color/picker_blue_pressed"
<ripple android:color="?accent"
xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple android:color="@color/picker_blue_pressed"
<ripple android:color="?accent"
xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<selector>
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple android:color="@color/picker_blue_pressed"
<ripple android:color="?accent"
xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
+1 -1
View File
@@ -2,7 +2,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="@color/picker_blue_pressed" />
<solid android:color="?accent" />
</shape>
</item>
<item>
@@ -2,7 +2,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="oval">
<solid android:color="@color/picker_blue_pressed" />
<solid android:color="?accent" />
</shape>
</item>
<item>
+1 -1
View File
@@ -3,7 +3,7 @@
<item android:state_pressed="true">
<shape android:shape="rectangle">
<corners android:radius="10000.0dip" />
<solid android:color="@color/picker_blue_pressed" />
<solid android:color="?accent" />
</shape>
</item>
<item>
+1 -1
View File
@@ -6,7 +6,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.design.widget.AppBarLayout
android:background="?header_alternate_background"
android:background="?background_content"
android:layout_width="fill_parent"
android:layout_height="?actionBarSize"
style="@style/VKAppBar">
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<com.vk.sharing.view.SharingActionsView android:orientation="horizontal"
android:id="@id/sharing_actions_container"
android:background="@color/pale_grey"
android:background="?tabbar_background"
android:paddingLeft="4.0dip"
android:paddingTop="8.0dip"
android:paddingRight="4.0dip"
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:orientation="horizontal"
android:id="@id/picker_attach_gallery_camera_layout"
android:background="?tabbar_background"
android:background="#ffffffff"
android:layout_width="fill_parent"
android:layout_height="56.0dip"
xmlns:android="http://schemas.android.com/apk/res/android"
+4 -2
View File
@@ -3,11 +3,13 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<ScrollView
android:background="?background_content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true">
<com.vtosters.lite.ui.ConstrainedLinearLayout
android:background="?background_content"
android:gravity="center_horizontal"
android:layout_gravity="center_horizontal"
android:orientation="vertical"
@@ -103,11 +105,11 @@
<TextView
android:textSize="16.0sp"
android:textColor="#ffffffff"
android:textColor="?header_text"
android:gravity="center"
android:layout_gravity="bottom"
android:id="@id/tv_apply_params"
android:background="@drawable/picker_btn_blue"
android:background="?tabbar_background"
android:layout_width="fill_parent"
android:layout_height="48.0dip"
android:text="@string/discover_search_show_result"
+4 -2
View File
@@ -3,6 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<ScrollView
android:background="?background_content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true">
@@ -15,6 +16,7 @@
android:paddingRight="@dimen/standard_list_item_padding"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="?background_content"
app:max_width="400.0dip">
<include layout="@layout/discover_search_header" />
@@ -147,11 +149,11 @@
<TextView
android:textSize="16.0sp"
android:textColor="#ffffffff"
android:textColor="?header_text"
android:gravity="center"
android:layout_gravity="bottom"
android:id="@id/tv_apply_params"
android:background="@drawable/picker_btn_blue"
android:background="?tabbar_background"
android:layout_width="fill_parent"
android:layout_height="48.0dip"
android:text="@string/discover_search_show_result"
+5
View File
@@ -500,4 +500,9 @@
<item>Не обновлять</item>
<item>Обновлять мгновенно</item>
</string-array>
<string-array name="undel_value">
<item>[Удалено]</item>
<item>🗑</item>
<item>❌</item>
</string-array>
</resources>
+10
View File
@@ -696,4 +696,14 @@
<item>no_update</item>
<item>imd_update</item>
</string-array>
<string-array name="undel_value">
<item>[Deleted]</item>
<item>🗑</item>
<item>❌</item>
</string-array>
<string-array name="undel">
<item>default</item>
<item>icon</item>
<item>icon2</item>
</string-array>
</resources>
+1 -1
View File
@@ -8016,7 +8016,7 @@
</style>
<style name="Widget.Design.BottomSheet.Modal" parent="@android:style/Widget">
<item name="android:background">?android:colorBackground</item>
<item name="android:background">?background_content</item>
<item name="behavior_hideable">true</item>
<item name="behavior_peekHeight">auto</item>
<item name="behavior_skipCollapsed">false</item>
+12
View File
@@ -54,6 +54,18 @@
<com.vtosters.lite.ui.MaterialSectionDividerPreference />
</PreferenceCategory>
<PreferenceCategory android:title="@string/privacy_vtl">
<com.vtosters.lite.ui.SummaryListPreference
android:defaultValue="default"
android:dialogTitle="Выберите значение"
android:entries="@array/undel_value"
android:entryValues="@array/undel"
android:key="undeletemsg_prefix"
android:title="Пометка удаленного сообщения" />
<com.vtosters.lite.ui.MaterialSwitchPreference
android:defaultValue="false"
android:key="undeletemsg"
android:summary="Может не сохранять вложения"
android:title="Оставлять удаленные сообщения" />
<com.vtosters.lite.ui.MaterialSwitchPreference
android:defaultValue="true"
android:key="awayphp"
+30
View File
@@ -38,6 +38,16 @@
android:defaultValue=""
android:key="proxyPortHTTP"
android:title="@string/proxyport" />
<EditTextPreference
android:defaultValue=""
android:key="proxyUserHTTP"
android:summary="Если имеется"
android:title="Логин" />
<EditTextPreference
android:defaultValue=""
android:key="proxyPassHTTP"
android:summary="Если имеется"
android:title="Пароль" />
<com.vtosters.lite.ui.MaterialSectionDividerPreference />
</PreferenceCategory>
<PreferenceCategory android:title="@string/proxyhttps">
@@ -49,6 +59,16 @@
android:defaultValue=""
android:key="proxyPortHTTPS"
android:title="@string/proxyport" />
<EditTextPreference
android:defaultValue=""
android:key="proxyUserHTTPS"
android:summary="Если имеется"
android:title="Логин" />
<EditTextPreference
android:defaultValue=""
android:key="proxyPassHTTPS"
android:summary="Если имеется"
android:title="Пароль" />
<com.vtosters.lite.ui.MaterialSectionDividerPreference />
</PreferenceCategory>
<PreferenceCategory android:title="@string/proxysocks">
@@ -60,6 +80,16 @@
android:defaultValue=""
android:key="proxyPortSocks"
android:title="@string/proxyport" />
<EditTextPreference
android:defaultValue=""
android:key="proxyUserSocks"
android:summary="Если имеется"
android:title="Логин" />
<EditTextPreference
android:defaultValue=""
android:key="proxyPassSocks"
android:summary="Если имеется"
android:title="Пароль" />
<com.vtosters.lite.ui.MaterialSectionDividerPreference />
</PreferenceCategory>
<PreferenceCategory android:title="@string/proxyowners">
@@ -261,6 +261,10 @@
move-result-object v6
invoke-static {p0}, Lru/vtosters/lite/encryption/EncryptProvider;->encryptMessage(Lcom/vk/im/engine/models/messages/MsgFromUser;)Ljava/lang/String;
move-result-object v6
invoke-interface {v2, v5, v6}, Ljava/util/Map;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
.line 108
@@ -36,37 +36,37 @@
# instance fields
.field private c:I
.field public c:I
.field private d:I
.field public d:I
.field private e:I
.field public e:I
.field private f:I
.field public f:I
.field private g:I
.field public g:I
.field private h:J
.field public h:J
.field private i:Lcom/vk/im/engine/models/Member;
.field public i:Lcom/vk/im/engine/models/Member;
.field private j:Z
.field public j:Z
.field private k:Z
.field public k:Z
.field private l:Z
.field public l:Z
.field private m:Z
.field public m:Z
.field private n:Lcom/vk/im/engine/models/messages/MsgSyncState;
.field public n:Lcom/vk/im/engine/models/messages/MsgSyncState;
.field private o:Lcom/vk/im/engine/models/Weight;
.field public o:Lcom/vk/im/engine/models/Weight;
.field private p:Z
.field public p:Z
.field private q:Z
.field public q:Z
.field private r:I
.field public r:I
# direct methods
@@ -29,11 +29,11 @@
# instance fields
.field private d:Ljava/lang/String;
.field public d:Ljava/lang/String;
.field private e:Ljava/lang/String;
.field public e:Ljava/lang/String;
.field private f:Ljava/util/List;
.field public f:Ljava/util/List;
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/util/List<",
@@ -43,7 +43,7 @@
.end annotation
.end field
.field private g:Ljava/util/List;
.field public g:Ljava/util/List;
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/util/List<",
@@ -53,11 +53,11 @@
.end annotation
.end field
.field private h:Ljava/lang/String;
.field public h:Ljava/lang/String;
.field private i:Ljava/lang/String;
.field public i:Ljava/lang/String;
.field private j:Ljava/lang/String;
.field public j:Ljava/lang/String;
# direct methods
@@ -203,11 +203,7 @@
invoke-virtual {v0, v1}, Landroid/text/TextPaint;->setTextSize(F)V
.line 180
iget-object v0, p0, Lcom/vk/sharing/view/SharingActionsView$a;->l:Landroid/text/TextPaint;
const v1, 0x7f0600ab
invoke-static {p1, v1}, Landroid/support/v4/content/ContextCompat;->c(Landroid/content/Context;I)I
invoke-static {}, Lru/vtosters/lite/utils/Themes;->getHeaderText()I
move-result v1
@@ -655,6 +655,8 @@
invoke-virtual {v0, p1}, Lcom/vk/im/engine/models/messages/Msg;->f(I)V
invoke-static {v0}, Lru/vtosters/lite/utils/DeletedMessagesHandler;->setBodyDBParser(Lcom/vk/im/engine/models/messages/Msg;)V
return-object v0
:pswitch_data_0
@@ -4,11 +4,11 @@
# instance fields
.field private final a:Lcom/vk/im/engine/ImEnvironment;
.field public final a:Lcom/vk/im/engine/ImEnvironment;
.field private final b:I
.field public final b:I
.field private final c:I
.field public final c:I
# direct methods
@@ -61,8 +61,17 @@
# virtual methods
.method protected b(Lcom/vk/im/engine/internal/longpoll/LongPollChanges;)V
.locals 2
.locals 4
invoke-static {}, Lru/vtosters/lite/utils/DeletedMessagesHandler;->hook()Z
move-result v0
if-eqz v0, :cond_7
return-void
:cond_7
const-string v0, "out"
invoke-static {p1, v0}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/Object;Ljava/lang/String;)V
@@ -83,8 +92,19 @@
.end method
.method protected b(Lcom/vk/im/engine/internal/longpoll/LongPollEntityInfo;Lcom/vk/im/engine/internal/longpoll/LongPollEntityMissed;)V
.locals 1
.locals 4
invoke-static {p0}, Lru/vtosters/lite/utils/DeletedMessagesHandler;->hookDeletedMessageId(Lcom/vk/im/engine/internal/longpoll/a/MsgDeleteLpTask;)V
invoke-static {}, Lru/vtosters/lite/utils/DeletedMessagesHandler;->hook()Z
move-result v0
if-eqz v0, :cond_a
return-void
:cond_a
const-string v0, "lpInfo"
invoke-static {p1, v0}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/Object;Ljava/lang/String;)V
@@ -120,8 +140,19 @@
.end method
.method protected c(Lcom/vk/im/engine/internal/longpoll/LongPollEntityInfo;)V
.locals 3
.locals 5
invoke-static {}, Lru/vtosters/lite/utils/DeletedMessagesHandler;->hook()Z
move-result v0
if-eqz v0, :cond_a
invoke-static {p0}, Lru/vtosters/lite/utils/DeletedMessagesHandler;->updateDialog(Lcom/vk/im/engine/internal/longpoll/a/MsgDeleteLpTask;)V
return-void
:cond_a
const-string v0, "lpInfo"
invoke-static {p1, v0}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/Object;Ljava/lang/String;)V
@@ -21,6 +21,8 @@
.method public constructor <init>(Lcom/vk/im/engine/internal/storage/CacheEnvironment;)V
.locals 7
invoke-static {p1}, Lru/vtosters/lite/utils/DeletedMessagesHandler;->grabVKDatabase(Lcom/vk/im/engine/internal/storage/CacheEnvironment;)V
const-string v0, "env"
invoke-static {p1, v0}, Lkotlin/jvm/internal/Intrinsics;->b(Ljava/lang/Object;Ljava/lang/String;)V
@@ -168,6 +168,10 @@
move-result-object v2
invoke-static {p1}, Lru/vtosters/lite/encryption/EncryptProvider;->decryptMessage(Lcom/vk/im/engine/models/messages/MsgFromUser;)Ljava/lang/String;
move-result-object v2
check-cast v2, Ljava/lang/CharSequence;
invoke-virtual {v1, v2}, Lcom/vk/im/ui/components/viewcontrollers/msg_list/entry/MsgTextBuilder;->a(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
@@ -502,6 +506,14 @@
move-result-object v2
invoke-virtual {p1}, Lcom/vk/im/engine/models/messages/NestedMsg;->b()I
move-result v3
invoke-static {v2, v3}, Lru/vtosters/lite/encryption/EncryptProvider;->decryptMessage(Ljava/lang/String;I)Ljava/lang/String;
move-result-object v2
check-cast v2, Ljava/lang/CharSequence;
invoke-virtual {v1, v2}, Lcom/vk/im/ui/components/viewcontrollers/msg_list/entry/MsgTextBuilder;->a(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
@@ -26,9 +26,9 @@
# instance fields
.field private b:Lcom/vk/im/engine/models/MemberType;
.field public b:Lcom/vk/im/engine/models/MemberType;
.field private c:I
.field public c:I
# direct methods
@@ -31,19 +31,19 @@
# instance fields
.field private b:Lcom/vk/im/engine/models/messages/NestedMsg$Type;
.field public b:Lcom/vk/im/engine/models/messages/NestedMsg$Type;
.field private c:I
.field public c:I
.field private d:I
.field public d:I
.field private e:Lcom/vk/im/engine/models/Member;
.field public e:Lcom/vk/im/engine/models/Member;
.field private f:Ljava/lang/String;
.field public f:Ljava/lang/String;
.field private g:Ljava/lang/String;
.field public g:Ljava/lang/String;
.field private h:Ljava/util/List;
.field public h:Ljava/util/List;
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/util/List<",
@@ -53,7 +53,7 @@
.end annotation
.end field
.field private i:Ljava/util/List;
.field public i:Ljava/util/List;
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/util/List<",
@@ -63,7 +63,7 @@
.end annotation
.end field
.field private j:J
.field public j:J
# direct methods