Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5dd616685d | ||
|
|
aff99be92d | ||
|
|
c255f1e498 | ||
|
|
70342daf07 | ||
|
|
f95672e57d | ||
|
|
8f5da42df4 | ||
|
|
4022903069 | ||
|
|
4600c185e4 | ||
|
|
30e8ec0038 |
@@ -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
|
||||
```
|
||||
|
||||

|
||||

|
||||
|
||||
@@ -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,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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -500,4 +500,9 @@
|
||||
<item>Не обновлять</item>
|
||||
<item>Обновлять мгновенно</item>
|
||||
</string-array>
|
||||
<string-array name="undel_value">
|
||||
<item>[Удалено]</item>
|
||||
<item>🗑</item>
|
||||
<item>❌</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
+2
@@ -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
|
||||
|
||||
+2
@@ -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
|
||||
|
||||
+12
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user