diff --git a/build/android/app/build.gradle b/build/android/app/build.gradle
index 42d79f66..2b0a6643 100644
--- a/build/android/app/build.gradle
+++ b/build/android/app/build.gradle
@@ -1,16 +1,16 @@
apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+
android {
- compileSdkVersion 29
+ compileSdkVersion 30
buildToolsVersion '30.0.3'
ndkVersion '22.1.7171670'
defaultConfig {
applicationId 'com.multicraft.game'
- minSdkVersion 16
- //noinspection OldTargetApi
- targetSdkVersion 29
- versionCode 150
- versionName "1.15.6"
- multiDexEnabled true
+ minSdkVersion 19
+ targetSdkVersion 30
+ versionCode 170
+ versionName "1.16.0"
}
// load properties
@@ -62,21 +62,10 @@ dependencies {
implementation project(':native')
/* Third-party libraries */
- implementation 'androidx.appcompat:appcompat:1.2.0'
- implementation 'androidx.appcompat:appcompat-resources:1.2.0'
- implementation 'androidx.multidex:multidex:2.0.1'
- implementation 'androidx.preference:preference:1.1.1'
- implementation 'io.reactivex.rxjava2:rxjava:2.2.21'
- implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
- //noinspection GradleDependency
- implementation 'com.squareup.okhttp3:okhttp:3.12.12'
- //noinspection GradleDependency
- implementation 'commons-io:commons-io:2.5'
- implementation 'gun0912.ted:tedpermission-rx2:2.2.3'
- //noinspection GradleDependency
- implementation 'net.lingala.zip4j:zip4j:2.6.4'
-
- /* Analytics libraries */
- //noinspection GradleDynamicVersion
- //implementation 'com.bugsnag:bugsnag-android-core:5.+'
+ implementation 'androidx.appcompat:appcompat:1.3.0'
+ implementation 'androidx.appcompat:appcompat-resources:1.3.0'
+ implementation 'com.google.android.material:material:1.4.0'
+ implementation 'io.reactivex.rxjava3:rxjava:3.0.13'
+ implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
+ implementation 'net.lingala.zip4j:zip4j:2.9.0'
}
diff --git a/build/android/app/src/main/AndroidManifest.xml b/build/android/app/src/main/AndroidManifest.xml
index 1431cd02..1780493b 100644
--- a/build/android/app/src/main/AndroidManifest.xml
+++ b/build/android/app/src/main/AndroidManifest.xml
@@ -4,37 +4,43 @@
package="com.multicraft.game"
android:installLocation="auto">
-
-
+
+
+
+
+
+ tools:ignore="UnusedAttribute"
+ tools:replace="android:fullBackupContent">
+ android:permission="android.permission.BIND_JOB_SERVICE" />
+
diff --git a/build/android/app/src/main/java/com/bugsnag/android/Bugsnag.java b/build/android/app/src/main/java/com/bugsnag/android/Bugsnag.java
deleted file mode 100644
index 698041ff..00000000
--- a/build/android/app/src/main/java/com/bugsnag/android/Bugsnag.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.bugsnag.android;
-
-import android.app.Application;
-import android.util.Log;
-
-public class Bugsnag {
- public static void notify(Throwable e) {
- Log.getStackTraceString(e);
- }
-
- public static void leaveBreadcrumb(String s) {
- Log.d("Bugsnag", s);
- }
-
- public static void start(Application application) {
- Log.d("Bugsnag", "Bugsnag initialized");
- }
-}
diff --git a/build/android/app/src/main/java/com/multicraft/game/CustomEditText.java b/build/android/app/src/main/java/com/multicraft/game/CustomEditText.kt
similarity index 52%
rename from build/android/app/src/main/java/com/multicraft/game/CustomEditText.java
rename to build/android/app/src/main/java/com/multicraft/game/CustomEditText.kt
index 03e9e827..a1d2c272 100644
--- a/build/android/app/src/main/java/com/multicraft/game/CustomEditText.java
+++ b/build/android/app/src/main/java/com/multicraft/game/CustomEditText.kt
@@ -1,7 +1,7 @@
/*
MultiCraft
-Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
-Copyright (C) 2014-2020 ubulem, Bektur Mambetov
+Copyright (C) 2014-2021 MoNTE48, Maksim Gamarnik
+Copyright (C) 2014-2021 ubulem, Bektur Mambetov
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
@@ -18,26 +18,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-package com.multicraft.game;
+package com.multicraft.game
-import android.content.Context;
-import android.view.KeyEvent;
-import android.view.inputmethod.InputMethodManager;
+import android.content.Context
+import android.util.AttributeSet
+import android.view.KeyEvent
+import android.view.inputmethod.InputMethodManager
-import androidx.appcompat.widget.AppCompatEditText;
-
-public class CustomEditText extends AppCompatEditText {
- public CustomEditText(Context context) {
- super(context);
- }
-
- @Override
- public boolean onKeyPreIme(int keyCode, KeyEvent event) {
+class CustomEditText constructor(context: Context, attrs: AttributeSet) :
+ com.google.android.material.textfield.TextInputEditText(context, attrs) {
+ override fun onKeyPreIme(keyCode: Int, event: KeyEvent): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK) {
- InputMethodManager mgr = (InputMethodManager)
- getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
- mgr.hideSoftInputFromWindow(this.getWindowToken(), 0);
+ val mgr = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ mgr.hideSoftInputFromWindow(this.windowToken, 0)
}
- return false;
+ return false
}
}
diff --git a/build/android/app/src/main/java/com/multicraft/game/GameActivity.java b/build/android/app/src/main/java/com/multicraft/game/GameActivity.java
index 1404de9d..a6e55c3f 100644
--- a/build/android/app/src/main/java/com/multicraft/game/GameActivity.java
+++ b/build/android/app/src/main/java/com/multicraft/game/GameActivity.java
@@ -1,7 +1,7 @@
/*
MultiCraft
-Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
-Copyright (C) 2014-2020 ubulem, Bektur Mambetov
+Copyright (C) 2014-2021 MoNTE48, Maksim Gamarnik
+Copyright (C) 2014-2021 ubulem, Bektur Mambetov
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
@@ -20,60 +20,42 @@ with this program; if not, write to the Free Software Foundation, Inc.,
package com.multicraft.game;
-import android.app.ActivityManager;
+import static android.content.res.Configuration.KEYBOARD_QWERTY;
+import static android.text.InputType.TYPE_CLASS_TEXT;
+import static android.text.InputType.TYPE_TEXT_FLAG_MULTI_LINE;
+import static android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD;
+import static com.multicraft.game.helpers.Utilities.getTotalMem;
+import static com.multicraft.game.helpers.Utilities.makeFullScreen;
+
import android.app.NativeActivity;
-import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
-import android.text.InputType;
import android.view.KeyEvent;
-import android.view.WindowManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager.LayoutParams;
+import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
+import android.widget.Button;
import androidx.appcompat.app.AlertDialog;
-import com.bugsnag.android.Bugsnag;
-import com.multicraft.game.helpers.PreferencesHelper;
-
-import io.reactivex.Completable;
-import io.reactivex.android.schedulers.AndroidSchedulers;
-import io.reactivex.disposables.Disposable;
-import io.reactivex.schedulers.Schedulers;
-
-import static android.content.res.Configuration.KEYBOARD_QWERTY;
-import static com.multicraft.game.AdManager.initAd;
-import static com.multicraft.game.AdManager.setAdsCallback;
-import static com.multicraft.game.AdManager.startAd;
-import static com.multicraft.game.AdManager.stopAd;
-import static com.multicraft.game.helpers.PreferencesHelper.getInstance;
-import static com.multicraft.game.helpers.Utilities.makeFullScreen;
+import com.google.android.material.textfield.TextInputEditText;
+import com.google.android.material.textfield.TextInputLayout;
public class GameActivity extends NativeActivity {
static {
try {
System.loadLibrary("MultiCraft");
- } catch (UnsatisfiedLinkError | OutOfMemoryError e) {
- Bugsnag.notify(e);
- System.exit(0);
- } catch (IllegalArgumentException i) {
- Bugsnag.notify(i);
- System.exit(0);
} catch (Error | Exception e) {
- Bugsnag.notify(e);
System.exit(0);
}
}
private int messageReturnCode = -1;
private String messageReturnValue = "";
- private boolean consent, isMultiPlayer;
- private PreferencesHelper pf;
- private Disposable adInitSub;
private boolean hasKeyboard;
- public static native void putMessageBoxResult(String text);
-
public static native void pauseGame();
public static native void keyboardEvent(boolean keyboard);
@@ -81,45 +63,20 @@ public class GameActivity extends NativeActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- Bundle bundle = getIntent().getExtras();
- consent = bundle.getBoolean("consent", true);
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON);
hasKeyboard = !(getResources().getConfiguration().hardKeyboardHidden == KEYBOARD_QWERTY);
keyboardEvent(hasKeyboard);
- pf = getInstance(this);
- if (pf.isAdsEnable()) {
- adInitSub = Completable.fromAction(() -> initAd(this, consent))
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(() -> setAdsCallback(this));
- }
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
- if (hasFocus)
- makeFullScreen(this);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- makeFullScreen(this);
+ if (hasFocus) makeFullScreen(getWindow());
}
@Override
public void onBackPressed() {
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- adInitSub.dispose();
- }
-
- public void showDialog(String acceptButton, String hint, String current, int editType) {
- runOnUiThread(() -> showDialogUI(hint, current, editType));
+ // Ignore the back press so MultiCraft can handle it
}
@Override
@@ -128,6 +85,12 @@ public class GameActivity extends NativeActivity {
pauseGame();
}
+ @Override
+ protected void onResume() {
+ super.onResume();
+ makeFullScreen(getWindow());
+ }
+
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
@@ -138,28 +101,37 @@ public class GameActivity extends NativeActivity {
}
}
+ @SuppressWarnings("unused")
+ public void showDialog(String s, String hint, String current, int editType) {
+ runOnUiThread(() -> showDialogUI(hint, current, editType));
+ }
+
private void showDialogUI(String hint, String current, int editType) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
- EditText editText = new CustomEditText(this);
- builder.setView(editText);
+ if (editType == 1) builder.setPositiveButton(R.string.done, null);
+ View layout = LayoutInflater.from(this).inflate(R.layout.input_text, null);
+ TextInputLayout inputLayout = layout.findViewById(R.id.inputLayout);
+ TextInputEditText editText = layout.findViewById(R.id.editText);
+ String hintText = (!hint.isEmpty()) ? hint : getResources().getString(
+ (editType == 3) ? R.string.input_password : R.string.input_text);
+ inputLayout.setHint(hintText);
+ builder.setView(layout);
AlertDialog alertDialog = builder.create();
editText.requestFocus();
- editText.setHint(hint);
editText.setText(current);
+ if (editType != 1) editText.setImeOptions(EditorInfo.IME_FLAG_NO_FULLSCREEN);
final InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
- imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,
- InputMethodManager.HIDE_IMPLICIT_ONLY);
- if (editType == 1)
- editText.setInputType(InputType.TYPE_CLASS_TEXT |
- InputType.TYPE_TEXT_FLAG_MULTI_LINE);
- else if (editType == 3)
- editText.setInputType(InputType.TYPE_CLASS_TEXT |
- InputType.TYPE_TEXT_VARIATION_PASSWORD);
- else
- editText.setInputType(InputType.TYPE_CLASS_TEXT);
+ imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
+ int inputType = TYPE_CLASS_TEXT;
+ if (editType == 1) {
+ inputType = inputType | TYPE_TEXT_FLAG_MULTI_LINE;
+ editText.setMaxLines(8);
+ } else if (editType == 3)
+ inputType = inputType | TYPE_TEXT_VARIATION_PASSWORD;
+ editText.setInputType(inputType);
editText.setSelection(editText.getText().length());
- editText.setOnKeyListener((view, KeyCode, event) -> {
- if (KeyCode == KeyEvent.KEYCODE_ENTER) {
+ editText.setOnEditorActionListener((view, KeyCode, event) -> {
+ if (KeyCode == KeyEvent.KEYCODE_ENTER || KeyCode == KeyEvent.KEYCODE_ENDCALL) {
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
messageReturnCode = 0;
messageReturnValue = editText.getText().toString();
@@ -169,8 +141,17 @@ public class GameActivity extends NativeActivity {
return false;
});
alertDialog.show();
+ Button button = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
+ if (button != null) {
+ button.setOnClickListener(view -> {
+ imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
+ messageReturnCode = 0;
+ messageReturnValue = editText.getText().toString();
+ alertDialog.dismiss();
+ });
+ }
alertDialog.setOnCancelListener(dialog -> {
- getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
+ getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
messageReturnValue = current;
messageReturnCode = -1;
});
@@ -180,6 +161,7 @@ public class GameActivity extends NativeActivity {
return messageReturnCode;
}
+ @SuppressWarnings("unused")
public String getDialogValue() {
messageReturnCode = -1;
return messageReturnValue;
@@ -190,25 +172,12 @@ public class GameActivity extends NativeActivity {
}
public float getMemoryMax() {
- ActivityManager actManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
- ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
- float memory = 1.0f;
- if (actManager != null) {
- actManager.getMemoryInfo(memInfo);
- memory = memInfo.totalMem * 1.0f / (1024 * 1024 * 1024);
- memory = Math.round(memory * 100) / 100.0f;
- }
- return memory;
+ return getTotalMem(this);
}
public void notifyServerConnect(boolean multiplayer) {
- isMultiPlayer = multiplayer;
- if (isMultiPlayer)
- stopAd();
}
public void notifyExitGame() {
- if (isMultiPlayer && pf.isAdsEnable())
- startAd(this, false, true);
}
}
diff --git a/build/android/app/src/main/java/com/multicraft/game/MainActivity.java b/build/android/app/src/main/java/com/multicraft/game/MainActivity.java
index 48fc61e2..8c3beb41 100644
--- a/build/android/app/src/main/java/com/multicraft/game/MainActivity.java
+++ b/build/android/app/src/main/java/com/multicraft/game/MainActivity.java
@@ -1,7 +1,7 @@
/*
MultiCraft
-Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
-Copyright (C) 2014-2020 ubulem, Bektur Mambetov
+Copyright (C) 2014-2021 MoNTE48, Maksim Gamarnik
+Copyright (C) 2014-2021 ubulem, Bektur Mambetov
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
@@ -20,95 +20,65 @@ with this program; if not, write to the Free Software Foundation, Inc.,
package com.multicraft.game;
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.ActivityNotFoundException;
+import static android.content.DialogInterface.BUTTON_NEUTRAL;
+import static android.provider.Settings.ACTION_WIFI_SETTINGS;
+import static android.provider.Settings.ACTION_WIRELESS_SETTINGS;
+import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
+import static com.multicraft.game.UnzipService.ACTION_FAILURE;
+import static com.multicraft.game.UnzipService.UNZIP_FAILURE;
+import static com.multicraft.game.UnzipService.UNZIP_SUCCESS;
+import static com.multicraft.game.helpers.Constants.FILES;
+import static com.multicraft.game.helpers.Constants.NO_SPACE_LEFT;
+import static com.multicraft.game.helpers.Constants.REQUEST_CONNECTION;
+import static com.multicraft.game.helpers.Constants.versionName;
+import static com.multicraft.game.helpers.PreferencesHelper.TAG_BUILD_NUMBER;
+import static com.multicraft.game.helpers.PreferencesHelper.TAG_LAUNCH_TIMES;
+import static com.multicraft.game.helpers.Utilities.addShortcut;
+import static com.multicraft.game.helpers.Utilities.copyInputStreamToFile;
+import static com.multicraft.game.helpers.Utilities.deleteFiles;
+import static com.multicraft.game.helpers.Utilities.finishApp;
+import static com.multicraft.game.helpers.Utilities.getIcon;
+import static com.multicraft.game.helpers.Utilities.isConnected;
+import static com.multicraft.game.helpers.Utilities.makeFullScreen;
+
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.graphics.BlendMode;
-import android.graphics.BlendModeColorFilter;
import android.graphics.Color;
-import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
-import android.net.Uri;
-import android.os.Build;
import android.os.Bundle;
-import android.os.Environment;
-import android.provider.Settings;
-import android.text.Html;
-import android.text.method.LinkMovementMethod;
-import android.view.Gravity;
import android.view.View;
-import android.view.WindowManager;
+import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
-import android.widget.Toast;
+import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.graphics.BlendModeColorFilterCompat;
+import androidx.core.graphics.BlendModeCompat;
-import com.bugsnag.android.Bugsnag;
-import com.multicraft.game.callbacks.CallBackListener;
-import com.multicraft.game.callbacks.DialogsCallback;
-import com.multicraft.game.helpers.AlertDialogHelper;
-import com.multicraft.game.helpers.PermissionHelper;
import com.multicraft.game.helpers.PreferencesHelper;
-import com.multicraft.game.helpers.Utilities;
-import com.multicraft.game.helpers.VersionManagerHelper;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.FilenameUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import io.reactivex.Completable;
-import io.reactivex.Observable;
-import io.reactivex.android.schedulers.AndroidSchedulers;
-import io.reactivex.disposables.Disposable;
-import io.reactivex.schedulers.Schedulers;
+import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
+import io.reactivex.rxjava3.core.Completable;
+import io.reactivex.rxjava3.core.Observable;
+import io.reactivex.rxjava3.disposables.Disposable;
+import io.reactivex.rxjava3.schedulers.Schedulers;
-import static com.multicraft.game.helpers.ApiLevelHelper.isGreaterOrEqual;
-import static com.multicraft.game.helpers.ApiLevelHelper.isGreaterOrEqualOreo;
-import static com.multicraft.game.helpers.ApiLevelHelper.isGreaterOrEqualQ;
-import static com.multicraft.game.helpers.PreferencesHelper.TAG_BUILD_NUMBER;
-import static com.multicraft.game.helpers.PreferencesHelper.TAG_CONSENT_ASKED;
-import static com.multicraft.game.helpers.PreferencesHelper.TAG_LAUNCH_TIMES;
-import static com.multicraft.game.helpers.Utilities.addShortcut;
-import static com.multicraft.game.helpers.Utilities.deleteFiles;
-import static com.multicraft.game.helpers.Utilities.getIcon;
-import static com.multicraft.game.helpers.Utilities.getStoreUrl;
-import static com.multicraft.game.helpers.Utilities.makeFullScreen;
-
-public class MainActivity extends AppCompatActivity implements CallBackListener, DialogsCallback {
- public final static Map zipLocations = new HashMap<>();
- private final static String SERVER_URL = "http://updates.multicraft.world/";
- public final static String UPDATE_LINK = SERVER_URL + "Android.json";
- private final static int REQUEST_CONNECTION = 104;
- private final static List EU_COUNTRIES = Arrays.asList(
- "AT", "BE", "BG", "HR", "CY", "CZ",
- "DK", "EE", "FI", "FR", "DE", "GR",
- "HU", "IE", "IT", "LV", "LT", "LU",
- "MT", "NL", "PL", "PT", "RO", "SK",
- "SI", "ES", "SE", "GB", "IS", "LI", "NO");
- private static String FILES, GAMES;
- private final String versionName = BuildConfig.VERSION_NAME;
- private String unzipLocation, appData;
- private boolean consent;
- private ProgressBar mProgressBar, mProgressBarIndeterminate;
- private TextView mLoading;
- private VersionManagerHelper versionManagerHelper = null;
+public class MainActivity extends AppCompatActivity {
+ private ProgressBar mProgressBar, mProgressBarIndet;
+ private TextView mLoadingText;
private PreferencesHelper pf;
- private Disposable connectionSub, versionManagerSub, cleanSub, copySub;
private final BroadcastReceiver myReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -116,38 +86,56 @@ public class MainActivity extends AppCompatActivity implements CallBackListener,
if (intent != null)
progress = intent.getIntExtra(UnzipService.ACTION_PROGRESS, 0);
if (progress >= 0) {
- if (mProgressBar != null) {
- showProgress(R.string.loading, R.string.loadingp, progress);
- }
+ showProgress(R.string.loading, R.string.loadingp, progress);
} else {
- runGame();
+ deleteFiles(Collections.singletonList(FILES), getCacheDir());
+ if (progress == UNZIP_FAILURE) {
+ String msg = intent.getStringExtra(ACTION_FAILURE);
+ showRestartDialog(msg);
+ } else if (progress == UNZIP_SUCCESS) {
+ pf.saveSettings(TAG_BUILD_NUMBER, versionName);
+ startNative();
+ }
}
}
};
+ private File externalStorage, filesDir, cacheDir;
+ private Disposable cleanSub, copySub, connectionSub;
- // helpful utilities
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ getWindow().addFlags(FLAG_KEEP_SCREEN_ON);
+ try {
+ getSupportActionBar().hide();
+ } catch (Exception ignored) {
+ }
setContentView(R.layout.activity_main);
+ mLoadingText = findViewById(R.id.tv_progress);
+ mProgressBar = findViewById(R.id.PB);
+ mProgressBarIndet = findViewById(R.id.PB_Indet);
+ boolean isException = false;
+ try {
+ filesDir = getFilesDir();
+ cacheDir = getCacheDir();
+ externalStorage = getExternalFilesDir(null);
+ if (filesDir == null || cacheDir == null || externalStorage == null)
+ throw new IOException(getString(R.string.space_error));
+ } catch (IOException e) {
+ isException = true;
+ String msg = getString(R.string.restart, e.getLocalizedMessage());
+ if (e.getMessage().contains(NO_SPACE_LEFT)) {
+ msg = NO_SPACE_LEFT;
+ }
+ showRestartDialog(msg);
+ }
+ if (isException) {
+ return;
+ }
pf = PreferencesHelper.getInstance(this);
IntentFilter filter = new IntentFilter(UnzipService.ACTION_UPDATE);
registerReceiver(myReceiver, filter);
- if (!isTaskRoot()) {
- finish();
- return;
- }
- addLaunchTimes();
- PermissionHelper permission = new PermissionHelper(this);
- permission.setListener(this);
- permission.askPermissions();
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- makeFullScreen(this);
+ lateInit();
}
@Override
@@ -158,357 +146,184 @@ public class MainActivity extends AppCompatActivity implements CallBackListener,
@Override
protected void onDestroy() {
super.onDestroy();
- if (connectionSub != null) connectionSub.dispose();
- if (versionManagerSub != null) versionManagerSub.dispose();
if (cleanSub != null) cleanSub.dispose();
if (copySub != null) copySub.dispose();
- unregisterReceiver(myReceiver);
- }
-
- private void initZipLocations() {
- File externalDir = getExternalFilesDir(null);
- unzipLocation = externalDir + File.separator;
- if (externalDir == null) {
- externalDir = Environment.getExternalStorageDirectory();
- unzipLocation = externalDir + File.separator + "Android/data/com.multicraft.game" + File.separator;
- }
- appData = getFilesDir() + File.separator;
- File cacheDir = getCacheDir();
- String cachePath = cacheDir + File.separator;
- if (cacheDir == null)
- cachePath = unzipLocation + "cache" + File.separator;
-
- FILES = cachePath + "Files.zip";
- GAMES = cachePath + "games.zip";
- zipLocations.put(FILES, appData);
- zipLocations.put(GAMES, appData);
- }
-
- private void addLaunchTimes() {
- int i = pf.getLaunchTimes();
- i++;
- pf.saveSettings(TAG_LAUNCH_TIMES, i);
- }
-
- private void createDataFolder() {
- File folder = new File(unzipLocation);
- if (!folder.mkdirs() && !folder.isDirectory())
- Bugsnag.leaveBreadcrumb(folder + " (unzipLocation) folder was not created");
- }
-
- // interface
- private void showProgress(int textMessage, int progressMessage, int progress) {
- if (mProgressBar.getVisibility() == View.GONE)
- updateViews(textMessage, View.VISIBLE, View.GONE, View.VISIBLE);
- else if (progress > 0) {
- mLoading.setText(String.format(getResources().getString(progressMessage), progress));
- mProgressBar.setProgress(progress);
- // colorize the progress bar
- Drawable progressDrawable = ((LayerDrawable)
- mProgressBar.getProgressDrawable()).getDrawable(1);
- int color = Color.rgb(255 - progress * 2, progress * 2, 25);
- if (isGreaterOrEqualQ())
- progressDrawable.setColorFilter(new BlendModeColorFilter(color, BlendMode.SRC_IN));
- else
- progressDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
- }
- }
-
- @Override
- public void onWindowFocusChanged(boolean hasFocus) {
- super.onWindowFocusChanged(hasFocus);
- if (hasFocus)
- makeFullScreen(this);
- }
-
- // GDPR check
- private void askGdpr() {
- if (pf.isAskConsent() && isGdprSubject())
- showGdprDialog();
- else {
- consent = true;
- startNative();
- }
- }
-
- private void init() {
- try {
- initZipLocations();
- } catch (Exception e) {
- showRestartDialog("");
- }
- mProgressBar = findViewById(R.id.PB1);
- mProgressBarIndeterminate = findViewById(R.id.PB2);
- mLoading = findViewById(R.id.tv_progress);
- RateMe.onStart(this);
- if (!pf.isCreateShortcut() && !isGreaterOrEqualOreo())
- addShortcut(this);
- checkAppVersion();
- }
-
- // game logic
- private void checkRateDialog() {
- if (RateMe.shouldShowRateDialog()) {
- updateViews(R.string.empty, View.GONE, View.GONE, View.GONE);
- RateMe.showRateDialog();
- RateMe.setListener(this);
- } else
- askGdpr();
- }
-
- void showUpdateDialog() {
- AlertDialogHelper dialogHelper = new AlertDialogHelper(this);
- dialogHelper.setListener(this);
- dialogHelper.setIcon(getIcon(this));
- dialogHelper.setTitle(getString(R.string.available));
- dialogHelper.setMessage(Html.fromHtml(
- versionManagerHelper.getMessage(), null, versionManagerHelper.getCustomTagHandler()));
- dialogHelper.setButtonPositive(getString(R.string.update));
- dialogHelper.setButtonNeutral(getString(R.string.later));
- dialogHelper.showAlert("VersionManager");
- }
-
- private void checkUrlVersion() {
- versionManagerHelper = new VersionManagerHelper(this);
- if (versionManagerHelper.isCheckVersion())
- versionManagerSub = Observable.fromCallable(() -> versionManagerHelper.getJson())
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .timeout(3000, TimeUnit.MILLISECONDS)
- .subscribe(result -> isShowDialog(versionManagerHelper.isShow(result)),
- throwable -> runOnUiThread(() -> isShowDialog(false)));
- else isShowDialog(false);
- }
-
- private void runGame() {
- deleteFiles(Arrays.asList(FILES, GAMES));
- pf.saveSettings(TAG_BUILD_NUMBER, versionName);
- connectionSub = checkConnection();
- }
-
- private void startNative() {
- Intent intent = new Intent(this, GameActivity.class);
- intent.putExtra("consent", consent);
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- startActivity(intent);
- }
-
- private boolean isGdprSubject() {
- String locale;
- if (isGreaterOrEqual(Build.VERSION_CODES.N))
- locale = getResources().getConfiguration().getLocales().get(0).getCountry();
- else
- locale = getResources().getConfiguration().locale.getCountry();
- return EU_COUNTRIES.contains(locale.toUpperCase());
+ if (connectionSub != null) connectionSub.dispose();
+ if (myReceiver != null) unregisterReceiver(myReceiver);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CONNECTION) {
- checkUrlVersion();
- } else askGdpr();
- }
-
- private void cleanUpOldFiles(boolean isAll) {
- updateViews(R.string.preparing, View.VISIBLE, View.VISIBLE, View.GONE);
- List filesList;
- if (isAll)
- filesList = Collections.singletonList(unzipLocation);
- else {
- filesList = Arrays.asList(unzipLocation + "cache",
- unzipLocation + "builtin", appData + "builtin",
- unzipLocation + "games", appData + "games",
- unzipLocation + "debug.txt");
- }
- cleanSub = Observable.fromCallable(() -> deleteFiles(filesList))
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(result -> startCopy(isAll));
- }
-
- private void checkAppVersion() {
- if (pf.getBuildNumber().equals(versionName)) {
- mProgressBarIndeterminate.setVisibility(View.VISIBLE);
- runGame();
- } else if (pf.getBuildNumber().equals("0")) {
- createDataFolder();
- cleanUpOldFiles(true);
- } else {
- createDataFolder();
- cleanUpOldFiles(false);
+ checkAppVersion();
}
}
- public void updateViews(int text, int textVisib, int progressIndetermVisib, int progressVisib) {
- mLoading.setText(text);
- mLoading.setVisibility(textVisib);
- mProgressBarIndeterminate.setVisibility(progressIndetermVisib);
- mProgressBar.setVisibility(progressVisib);
+ @Override
+ protected void onResume() {
+ super.onResume();
+ makeFullScreen(getWindow());
}
- public void isShowDialog(boolean flag) {
- if (flag) {
- updateViews(R.string.loading, View.VISIBLE, View.VISIBLE, View.GONE);
- showUpdateDialog();
- } else
- checkRateDialog();
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ super.onWindowFocusChanged(hasFocus);
+ if (hasFocus) makeFullScreen(getWindow());
}
+ private void addLaunchTimes() {
+ int launchTimes = pf.getLaunchTimes() + 1;
+ pf.saveSettings(TAG_LAUNCH_TIMES, launchTimes);
+ }
+
+ // interface
+ private void showProgress(int textMessage, int progressMessage, int progress) {
+ if (mProgressBar == null) return;
+ if (mProgressBar.getVisibility() == View.GONE) {
+ updateViews(textMessage, View.GONE, View.VISIBLE);
+ mProgressBar.setProgress(0);
+ } else if (progress > 0) {
+ mLoadingText.setText(String.format(getResources().getString(progressMessage), progress));
+ mProgressBar.setProgress(progress);
+ // colorize the progress bar
+ Drawable progressDrawable = ((LayerDrawable)
+ mProgressBar.getProgressDrawable()).getDrawable(1);
+ int color = Color.rgb(255 - progress * 2, progress * 2, 25);
+ progressDrawable.setColorFilter(
+ BlendModeColorFilterCompat.createBlendModeColorFilterCompat(color, BlendModeCompat.SRC_IN));
+ }
+ }
+
+ private void lateInit() {
+ addLaunchTimes();
+ if (!pf.isCreateShortcut()) addShortcut(this);
+ connectionSub = checkConnection();
+ }
+
+ // check connection available
private Disposable checkConnection() {
- return Observable.fromCallable(Utilities::isReachable)
+ return Observable.fromCallable(() -> isConnected(this))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
- .timeout(4000, TimeUnit.MILLISECONDS)
.subscribe(result -> {
- if (result) checkUrlVersion();
+ if (result) checkAppVersion();
else showConnectionDialog();
},
throwable -> runOnUiThread(this::showConnectionDialog));
}
- private void startCopy(boolean isAll) {
- String[] zips;
- if (isAll)
- zips = new String[]{FILES, GAMES};
- else
- zips = new String[]{FILES, GAMES};
- copySub = Completable.fromAction(() -> copyAssets(zips))
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(() -> startUnzipService(zips),
- throwable -> {
- if (throwable.getLocalizedMessage().contains("ENOSPC"))
- showRestartDialog("ENOSPC");
- else showRestartDialog("UKNWN");
- });
- }
-
- private void copyAssets(String[] zips) throws IOException {
- for (String zipName : zips) {
- String filename = FilenameUtils.getName(zipName);
- try (InputStream in = getAssets().open(filename)) {
- FileUtils.copyInputStreamToFile(in, new File(zipName));
- }
+ // connection dialog
+ private void showConnectionDialog() {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setIcon(getIcon(this))
+ .setTitle(R.string.conn_title)
+ .setMessage(R.string.conn_message)
+ .setPositiveButton(R.string.conn_wifi, (dialogInterface, i) -> startHandledActivity(new Intent(ACTION_WIFI_SETTINGS)))
+ .setNegativeButton(R.string.conn_mobile, (dialogInterface, i) -> startHandledActivity(new Intent(ACTION_WIRELESS_SETTINGS)))
+ .setNeutralButton(R.string.ignore, (dialogInterface, i) -> checkAppVersion())
+ .setCancelable(false);
+ final AlertDialog dialog = builder.create();
+ makeFullScreen(dialog.getWindow());
+ if (!isFinishing()) {
+ dialog.show();
+ Button button = dialog.getButton(BUTTON_NEUTRAL);
+ if (button != null) button.setTextColor(Color.RED);
}
}
- private void startUnzipService(String[] file) {
+ private void startHandledActivity(Intent intent) {
+ try {
+ startActivityForResult(intent, REQUEST_CONNECTION);
+ } catch (Exception e) {
+ checkAppVersion();
+ }
+ }
+
+ private void startNative() {
+ Intent intent = new Intent(this, GameActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ startActivity(intent);
+ }
+
+ private void cleanUpOldFiles() {
+ updateViews(R.string.preparing, View.VISIBLE, View.GONE);
+ List filesList = Arrays.asList(
+ new File(externalStorage, "cache"),
+ new File(externalStorage, "debug.txt"),
+ new File(filesDir, "builtin"),
+ new File(cacheDir, FILES)
+ );
+ Completable delObs = Completable.fromAction(() -> deleteFiles(filesList));
+ cleanSub = delObs.subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(this::startCopy);
+ }
+
+ private void checkAppVersion() {
+ String prefVersion;
+ try {
+ prefVersion = pf.getBuildNumber();
+ } catch (ClassCastException e) {
+ prefVersion = "1";
+ }
+
+ if (prefVersion.equals(versionName))
+ startNative();
+ else
+ cleanUpOldFiles();
+ }
+
+ private void updateViews(int text, int progressIndetVisib, int progressVisib) {
+ mLoadingText.setText(text);
+ mLoadingText.setVisibility(View.VISIBLE);
+ mProgressBarIndet.setVisibility(progressIndetVisib);
+ mProgressBar.setVisibility(progressVisib);
+ }
+
+ private void startCopy() {
+ List zips = new ArrayList<>(Collections.singletonList(FILES));
+
+ copySub = Observable.fromCallable(() -> copyAssets(zips))
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(result -> {
+ if (result) startUnzipService(zips);
+ });
+ }
+
+ private boolean copyAssets(List zips) {
+ for (String zipName : zips) {
+ try (InputStream in = getAssets().open("data/" + zipName)) {
+ copyInputStreamToFile(new File(cacheDir, zipName), in);
+ } catch (IOException e) {
+ if (e.getLocalizedMessage().contains(NO_SPACE_LEFT))
+ runOnUiThread(() -> showRestartDialog(NO_SPACE_LEFT));
+ else {
+ runOnUiThread(() -> showRestartDialog(e.getLocalizedMessage()));
+ }
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void startUnzipService(List file) {
Intent intent = new Intent(this, UnzipService.class);
- intent.putExtra(UnzipService.EXTRA_KEY_IN_FILE, file);
- startService(intent);
+ intent.putStringArrayListExtra(UnzipService.EXTRA_KEY_IN_FILE, (ArrayList) file);
+ UnzipService.enqueueWork(this, intent);
}
private void showRestartDialog(final String source) {
- String message;
- if ("ENOSPC".equals(source))
- message = getString(R.string.no_space);
- else
- message = getString(R.string.restart);
- final AlertDialogHelper dialogHelper = new AlertDialogHelper(this);
- dialogHelper.setListener(this);
- dialogHelper.setMessage(message);
- dialogHelper.setButtonPositive(getString(android.R.string.ok));
- dialogHelper.showAlert("Restart");
- }
-
- private void restartApp() {
- Intent intent = new Intent(getApplicationContext(), MainActivity.class);
- int mPendingIntentId = 1337;
- AlarmManager mgr = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
- if (mgr != null)
- mgr.set(AlarmManager.RTC, System.currentTimeMillis(), PendingIntent.getActivity(
- getApplicationContext(), mPendingIntentId, intent, PendingIntent.FLAG_CANCEL_CURRENT));
- System.exit(0);
- }
-
- @Override
- public void onEvent(boolean isContinue) {
- if (isFinishing()) return;
- if (isContinue) init();
- else finish();
- }
-
- private void showGdprDialog() {
- AlertDialogHelper dialogHelper = new AlertDialogHelper(this);
- dialogHelper.setListener(this);
- dialogHelper.setIcon(getIcon(this));
- dialogHelper.setTitle(getString(R.string.app_name));
- TextView tv = new TextView(this);
- tv.setText(R.string.gdpr_main_text);
- tv.setPadding(20, 0, 20, 0);
- tv.setGravity(Gravity.CENTER);
- tv.setMovementMethod(LinkMovementMethod.getInstance());
- dialogHelper.setTV(tv);
- dialogHelper.setButtonPositive(getString(R.string.gdpr_agree));
- dialogHelper.setButtonNegative(getString(R.string.gdpr_disagree));
- dialogHelper.showAlert("GdprDialog");
- }
-
- private void showConnectionDialog() {
- AlertDialogHelper dialogHelper = new AlertDialogHelper(this);
- dialogHelper.setListener(this);
- dialogHelper.setMessage(getString(R.string.conn_message));
- dialogHelper.setButtonPositive(getString(R.string.conn_wifi));
- dialogHelper.setButtonNegative(getString(R.string.conn_mobile));
- dialogHelper.setButtonNeutral(getString(R.string.ignore));
- dialogHelper.showAlert("ConnectionDialog");
- }
-
- @Override
- public void onPositive(String source) {
- if ("RateMe".equals(source)) {
- Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(getStoreUrl()));
- startActivity(intent);
- Toast.makeText(this, R.string.thank, Toast.LENGTH_LONG).show();
- finish();
- } else if ("Restart".equals(source))
- restartApp();
- else if ("ConnectionDialog".equals(source))
- try {
- startActivityForResult(new Intent(Settings.ACTION_WIFI_SETTINGS), REQUEST_CONNECTION);
- } catch (ActivityNotFoundException e) {
- Bugsnag.notify(e);
- askGdpr();
- }
- else if ("GdprDialog".equals(source)) {
- pf.saveSettings(TAG_CONSENT_ASKED, false);
- consent = true;
- startNative();
- } else {
- versionManagerHelper.updateNow(versionManagerHelper.getUpdateUrl());
- finish();
- }
- }
-
- @Override
- public void onNegative(String source) {
- if ("RateMe".equals(source))
- askGdpr();
- else if ("ConnectionDialog".equals(source))
- try {
- startActivityForResult(new Intent(Settings.ACTION_WIRELESS_SETTINGS), REQUEST_CONNECTION);
- } catch (ActivityNotFoundException e) {
- Bugsnag.notify(e);
- askGdpr();
- }
- else if ("GdprDialog".equals(source)) {
- pf.saveSettings(TAG_CONSENT_ASKED, false);
- consent = false;
- startNative();
- } else
- checkRateDialog();
- }
-
- @Override
- public void onNeutral(String source) {
- if ("RateMe".equals(source))
- askGdpr();
- else if ("ConnectionDialog".equals(source))
- askGdpr();
- else {
- versionManagerHelper.remindMeLater();
- checkRateDialog();
- }
+ boolean space = NO_SPACE_LEFT.equals(source);
+ String message = space ? getString(R.string.no_space) : source;
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setMessage(message)
+ .setPositiveButton(R.string.ok, (dialogInterface, i) -> finishApp(!space, this))
+ .setCancelable(false);
+ final AlertDialog dialog = builder.create();
+ makeFullScreen(dialog.getWindow());
+ if (!isFinishing())
+ dialog.show();
}
}
diff --git a/build/android/app/src/main/java/com/multicraft/game/MyApplication.java b/build/android/app/src/main/java/com/multicraft/game/MyApplication.java
deleted file mode 100644
index 3972f78d..00000000
--- a/build/android/app/src/main/java/com/multicraft/game/MyApplication.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-MultiCraft
-Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
-Copyright (C) 2014-2020 ubulem, Bektur Mambetov
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 3.0 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-package com.multicraft.game;
-
-import androidx.multidex.MultiDexApplication;
-
-import com.bugsnag.android.Bugsnag;
-
-public class MyApplication extends MultiDexApplication {
- @Override
- public void onCreate() {
- super.onCreate();
- Bugsnag.start(this);
- }
-}
diff --git a/build/android/app/src/main/java/com/multicraft/game/RateMe.java b/build/android/app/src/main/java/com/multicraft/game/RateMe.java
deleted file mode 100644
index 316ce043..00000000
--- a/build/android/app/src/main/java/com/multicraft/game/RateMe.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
-MultiCraft
-Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
-Copyright (C) 2014-2020 ubulem, Bektur Mambetov
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 3.0 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-package com.multicraft.game;
-
-import android.app.Dialog;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.view.View;
-import android.widget.RatingBar;
-import android.widget.Toast;
-
-import androidx.appcompat.app.AppCompatActivity;
-
-import com.bugsnag.android.Bugsnag;
-import com.multicraft.game.callbacks.DialogsCallback;
-import com.multicraft.game.helpers.PreferencesHelper;
-
-import java.lang.ref.WeakReference;
-import java.util.Date;
-
-import static com.multicraft.game.helpers.ApiLevelHelper.isGreaterOrEqualKitkat;
-
-class RateMe {
- private static final int INSTALL_DAYS = 5;
- private static final int LAUNCH_TIMES = 4;
- private static final String PREF_NAME = "RateMe";
- private static final String KEY_INSTALL_DATE = "rta_install_date";
- private static final String KEY_OPT_OUT = "rta_opt_out";
- private static Date mInstallDate = new Date();
- private static boolean mOptOut = false;
- private static DialogsCallback sCallback = null;
-
- private static WeakReference activityRef = null;
-
- static void setListener(DialogsCallback callback) {
- sCallback = callback;
- }
-
- static void onStart(AppCompatActivity activity) {
- activityRef = new WeakReference<>(activity);
- SharedPreferences pref = activity.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
- Editor editor = pref.edit();
- // If it is the first launch, save the date in shared preference.
- if (pref.getLong(KEY_INSTALL_DATE, 0) == 0L)
- storeInstallDate(activity, editor);
- editor.apply();
-
- mInstallDate = new Date(pref.getLong(KEY_INSTALL_DATE, 0));
- mOptOut = pref.getBoolean(KEY_OPT_OUT, false);
- }
-
- static boolean shouldShowRateDialog() {
- if (mOptOut)
- return false;
- else {
- if (PreferencesHelper.getInstance(activityRef.get()).getLaunchTimes() % LAUNCH_TIMES == 0)
- return true;
- long threshold = INSTALL_DAYS * 24 * 60 * 60 * 1000L;
- return new Date().getTime() - mInstallDate.getTime() >= threshold;
- }
- }
-
- static void showRateDialog() {
- final AppCompatActivity activity = activityRef.get();
- final Dialog dialog = new Dialog(activity, R.style.RateMe);
- dialog.setCancelable(false);
- if (isGreaterOrEqualKitkat())
- dialog.getWindow().getDecorView().setSystemUiVisibility(
- View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
- dialog.setContentView(R.layout.rate_dialog);
- RatingBar ratingBar = dialog.findViewById(R.id.ratingBar);
- ratingBar.setOnRatingBarChangeListener((ratingBar1, rating, fromUser) -> {
- if (rating >= 4) {
- sCallback.onPositive("RateMe");
- dialog.dismiss();
- setOptOut(activity);
- } else {
- sCallback.onNegative("RateMe");
- dialog.dismiss();
- Toast.makeText(activity, R.string.sad, Toast.LENGTH_LONG).show();
- clearSharedPreferences(activity);
- }
- });
- dialog.setOnCancelListener(dialog1 -> {
- sCallback.onNeutral("RateMe");
- clearSharedPreferences(activity);
- });
- if (!activity.isFinishing())
- dialog.show();
- else
- sCallback.onNegative("RateMe");
- }
-
- private static void clearSharedPreferences(AppCompatActivity activity) {
- Editor editor = activity.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit();
- editor.remove(KEY_INSTALL_DATE);
- editor.apply();
- }
-
- private static void setOptOut(final AppCompatActivity activity) {
- Editor editor = activity.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit();
- editor.putBoolean(KEY_OPT_OUT, true);
- editor.apply();
- }
-
- private static void storeInstallDate(final AppCompatActivity activity, Editor editor) {
- Date installDate = new Date();
- PackageManager packageManager = activity.getPackageManager();
- try {
- PackageInfo pkgInfo = packageManager.getPackageInfo(activity.getPackageName(), 0);
- installDate = new Date(pkgInfo.firstInstallTime);
- } catch (PackageManager.NameNotFoundException e) {
- Bugsnag.notify(e);
- }
- editor.putLong(KEY_INSTALL_DATE, installDate.getTime());
- }
-}
diff --git a/build/android/app/src/main/java/com/multicraft/game/RemoteSettings.java b/build/android/app/src/main/java/com/multicraft/game/RemoteSettings.java
deleted file mode 100644
index 0826027c..00000000
--- a/build/android/app/src/main/java/com/multicraft/game/RemoteSettings.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-MultiCraft
-Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
-Copyright (C) 2014-2020 ubulem, Bektur Mambetov
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 3.0 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-package com.multicraft.game;
-
-import java.util.List;
-
-public class RemoteSettings {
- private int versionCode = 0;
- private List badVersionCodes;
- private String packageName, content;
- private int adsDelay = -1;
- private int adsRepeat = -1;
- private boolean adsEnabled = true;
-
- public int getVersionCode() {
- return versionCode;
- }
-
- public void setVersionCode(int versionCode) {
- this.versionCode = versionCode;
- }
-
- public List getBadVersionCodes() {
- return badVersionCodes;
- }
-
- public void setBadVersionCodes(List badVersionCodes) {
- this.badVersionCodes = badVersionCodes;
- }
-
- public String getPackageName() {
- return packageName;
- }
-
- public void setPackageName(String packageName) {
- this.packageName = packageName;
- }
-
- public String getContent() {
- return content;
- }
-
- public void setContent(String content) {
- this.content = content;
- }
-
- public int getAdsDelay() {
- return adsDelay;
- }
-
- public void setAdsDelay(int adsDelay) {
- this.adsDelay = adsDelay;
- }
-
- public int getAdsRepeat() {
- return adsRepeat;
- }
-
- public void setAdsRepeat(int adsRepeat) {
- this.adsRepeat = adsRepeat;
- }
-
- public boolean isAdsEnabled() {
- return adsEnabled;
- }
-
- public void setAdsEnabled(boolean adsEnabled) {
- this.adsEnabled = adsEnabled;
- }
-}
diff --git a/build/android/app/src/main/java/com/multicraft/game/UnzipService.java b/build/android/app/src/main/java/com/multicraft/game/UnzipService.java
deleted file mode 100644
index 22944c2b..00000000
--- a/build/android/app/src/main/java/com/multicraft/game/UnzipService.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
-MultiCraft
-Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
-Copyright (C) 2014-2020 ubulem, Bektur Mambetov
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 3.0 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-package com.multicraft.game;
-
-import android.app.IntentService;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.content.Context;
-import android.content.Intent;
-
-import com.bugsnag.android.Bugsnag;
-
-import net.lingala.zip4j.ZipFile;
-import net.lingala.zip4j.io.inputstream.ZipInputStream;
-import net.lingala.zip4j.model.LocalFileHeader;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-import static com.multicraft.game.MainActivity.zipLocations;
-import static com.multicraft.game.helpers.ApiLevelHelper.isGreaterOrEqualOreo;
-
-public class UnzipService extends IntentService {
- public static final String ACTION_UPDATE = "com.multicraft.game.UPDATE";
- public static final String EXTRA_KEY_IN_FILE = "file";
- public static final String ACTION_PROGRESS = "progress";
- private final int id = 1;
- private NotificationManager mNotifyManager;
-
- public UnzipService() {
- super("com.multicraft.game.UnzipService");
- }
-
- private void isDir(String dir, String unzipLocation) {
- File f = new File(unzipLocation + dir);
- if (!f.mkdirs() && !f.isDirectory())
- Bugsnag.leaveBreadcrumb(f + " (destination) folder was not created");
- }
-
- @Override
- protected void onHandleIntent(Intent intent) {
- createNotification();
- unzip(intent);
- }
-
- private String getSettings() {
- return getString(R.string.gdpr_main_text);
- }
-
- private void createNotification() {
- // There are hardcoding only for show it's just strings
- String name = "com.multicraft.game";
- String channelId = "MultiCraft channel"; // The user-visible name of the channel.
- String description = "notifications from MultiCraft"; // The user-visible description of the channel.
- Notification.Builder builder;
- if (mNotifyManager == null)
- mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- if (isGreaterOrEqualOreo()) {
- int importance = NotificationManager.IMPORTANCE_LOW;
- NotificationChannel mChannel = null;
- if (mNotifyManager != null)
- mChannel = mNotifyManager.getNotificationChannel(channelId);
- if (mChannel == null) {
- mChannel = new NotificationChannel(channelId, name, importance);
- mChannel.setDescription(description);
- // Configure the notification channel, NO SOUND
- mChannel.setSound(null, null);
- mChannel.enableLights(false);
- mChannel.enableVibration(false);
- mNotifyManager.createNotificationChannel(mChannel);
- }
- builder = new Notification.Builder(this, channelId);
- } else
- builder = new Notification.Builder(this);
- builder.setContentTitle(getString(R.string.notification_title))
- .setContentText(getString(R.string.notification_description))
- .setSmallIcon(R.drawable.update);
- mNotifyManager.notify(id, builder.build());
- }
-
- private void unzip(Intent intent) {
- String[] zips = intent.getStringArrayExtra(EXTRA_KEY_IN_FILE);
- int per = 0;
- int size = getSummarySize(zips);
- for (String zip : zips) {
- File zipFile = new File(zip);
- LocalFileHeader localFileHeader;
- int readLen;
- byte[] readBuffer = new byte[8192];
- try (FileInputStream fileInputStream = new FileInputStream(zipFile);
- ZipInputStream zipInputStream = new ZipInputStream(fileInputStream)) {
- while ((localFileHeader = zipInputStream.getNextEntry()) != null) {
- String fileName = localFileHeader.getFileName();
- if (localFileHeader.isDirectory()) {
- ++per;
- isDir(fileName, zipLocations.get(zip));
- } else {
- File extractedFile = new File(fileName);
- publishProgress(100 * ++per / size);
- try (OutputStream outputStream = new FileOutputStream(zipLocations.get(zip) + extractedFile)) {
- while ((readLen = zipInputStream.read(readBuffer)) != -1) {
- outputStream.write(readBuffer, 0, readLen);
- }
- }
- }
- }
- } catch (FileNotFoundException e) {
- Bugsnag.notify(e);
- } catch (IOException e) {
- Bugsnag.notify(e);
- }
- }
- }
-
- private void publishProgress(int progress) {
- Intent intentUpdate = new Intent(ACTION_UPDATE);
- intentUpdate.putExtra(ACTION_PROGRESS, progress);
- sendBroadcast(intentUpdate);
- }
-
- private int getSummarySize(String[] zips) {
- int size = 0;
- for (String z : zips) {
- try {
- ZipFile zipFile = new ZipFile(z);
- size += zipFile.getFileHeaders().size();
- } catch (IOException e) {
- Bugsnag.notify(e);
- }
- }
- return size;
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- mNotifyManager.cancel(id);
- publishProgress(-1);
- }
-}
diff --git a/build/android/app/src/main/java/com/multicraft/game/UnzipService.kt b/build/android/app/src/main/java/com/multicraft/game/UnzipService.kt
new file mode 100644
index 00000000..e1e86775
--- /dev/null
+++ b/build/android/app/src/main/java/com/multicraft/game/UnzipService.kt
@@ -0,0 +1,156 @@
+/*
+MultiCraft
+Copyright (C) 2014-2021 MoNTE48, Maksim Gamarnik
+Copyright (C) 2014-2021 ubulem, Bektur Mambetov
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3.0 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+package com.multicraft.game
+
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.content.Context
+import android.content.Intent
+import androidx.core.app.JobIntentService
+import com.multicraft.game.helpers.ApiLevelHelper.isOreo
+import com.multicraft.game.helpers.Utilities.copyInputStreamToFile
+import net.lingala.zip4j.ZipFile
+import net.lingala.zip4j.io.inputstream.ZipInputStream
+import net.lingala.zip4j.model.LocalFileHeader
+import java.io.File
+import java.io.FileInputStream
+import java.io.IOException
+import java.util.*
+
+class UnzipService : JobIntentService() {
+ private val id = 1
+ private var mNotifyManager: NotificationManager? = null
+ private lateinit var failureMessage: String
+ private var isSuccess = true
+
+ override fun onHandleWork(intent: Intent) {
+ createNotification()
+ unzip(intent)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ if (mNotifyManager != null) mNotifyManager!!.cancel(id)
+ publishProgress(if (isSuccess) UNZIP_SUCCESS else UNZIP_FAILURE)
+ }
+
+ private fun createNotification() {
+ val name = "com.multicraft.game"
+ val channelId = "MultiCraft channel"
+ val description = "notifications from MultiCraft"
+ val builder: Notification.Builder
+ if (mNotifyManager == null) mNotifyManager =
+ getSystemService(NOTIFICATION_SERVICE) as NotificationManager
+ if (isOreo) {
+ val importance = NotificationManager.IMPORTANCE_LOW
+ var mChannel: NotificationChannel? = null
+ if (mNotifyManager != null) mChannel =
+ mNotifyManager!!.getNotificationChannel(channelId)
+ if (mChannel == null) {
+ mChannel = NotificationChannel(channelId, name, importance)
+ mChannel.description = description
+ // Configure the notification channel, NO SOUND
+ mChannel.setSound(null, null)
+ mChannel.enableLights(false)
+ mChannel.enableVibration(false)
+ mNotifyManager!!.createNotificationChannel(mChannel)
+ }
+ builder = Notification.Builder(this, channelId)
+ } else @Suppress("DEPRECATION") {
+ builder = Notification.Builder(this)
+ }
+ builder.setContentTitle(getString(R.string.notification_title))
+ .setContentText(getString(R.string.notification_description))
+ .setSmallIcon(R.drawable.update)
+ mNotifyManager!!.notify(id, builder.build())
+ }
+
+ @Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
+ private fun unzip(intent: Intent?) {
+ try {
+ val zips: ArrayList =
+ intent?.getStringArrayListExtra(EXTRA_KEY_IN_FILE)
+ ?: throw NullPointerException("No data received")
+ val cache = cacheDir.toString()
+ val files = filesDir.toString()
+ var per = 0
+ val size = getSummarySize(zips, cache)
+ for (zip in zips) {
+ val zipFile = File(cache, zip)
+ var localFileHeader: LocalFileHeader?
+ FileInputStream(zipFile).use { fileInputStream ->
+ ZipInputStream(
+ fileInputStream
+ ).use { zipInputStream ->
+ while (zipInputStream.nextEntry.also { localFileHeader = it } != null) {
+ if (localFileHeader == null) continue
+ val extracted = File(files, localFileHeader!!.fileName)
+ if (localFileHeader!!.isDirectory)
+ extracted.mkdirs()
+ else
+ extracted.copyInputStreamToFile(zipInputStream)
+ ++per
+ publishProgress(100 * per / size)
+ }
+ }
+ }
+ }
+ } catch (e: IOException) {
+ failureMessage = e.localizedMessage
+ isSuccess = false
+ } catch (e: NullPointerException) {
+ failureMessage = e.localizedMessage
+ isSuccess = false
+ }
+ }
+
+ private fun publishProgress(progress: Int) {
+ val intentUpdate = Intent(ACTION_UPDATE)
+ intentUpdate.putExtra(ACTION_PROGRESS, progress)
+ if (!isSuccess) intentUpdate.putExtra(ACTION_FAILURE, failureMessage)
+ sendBroadcast(intentUpdate)
+ }
+
+ private fun getSummarySize(zips: List, path: String): Int {
+ var size = 1
+ for (zip in zips) {
+ val zipFile = ZipFile(File(path, zip))
+ size += zipFile.fileHeaders.size
+ }
+ return size
+ }
+
+ companion object {
+ const val ACTION_UPDATE = "com.multicraft.game.UPDATE"
+ const val EXTRA_KEY_IN_FILE = "com.multicraft.game.file"
+ const val ACTION_PROGRESS = "com.multicraft.game.progress"
+ const val ACTION_FAILURE = "com.multicraft.game.failure"
+ const val UNZIP_SUCCESS = -1
+ const val UNZIP_FAILURE = -2
+ private const val JOB_ID = 1
+
+ @JvmStatic
+ fun enqueueWork(context: Context, work: Intent) {
+ enqueueWork(context, UnzipService::class.java, JOB_ID, work)
+ }
+ }
+}
diff --git a/build/android/app/src/main/java/com/multicraft/game/callbacks/CallBackListener.java b/build/android/app/src/main/java/com/multicraft/game/callbacks/CallBackListener.java
deleted file mode 100644
index 1a7bd889..00000000
--- a/build/android/app/src/main/java/com/multicraft/game/callbacks/CallBackListener.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-MultiCraft
-Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
-Copyright (C) 2014-2020 ubulem, Bektur Mambetov
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 3.0 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-package com.multicraft.game.callbacks;
-
-public interface CallBackListener {
- void onEvent(boolean isContinue);
-}
diff --git a/build/android/app/src/main/java/com/multicraft/game/helpers/AlertDialogHelper.java b/build/android/app/src/main/java/com/multicraft/game/helpers/AlertDialogHelper.java
deleted file mode 100644
index 339e5dc5..00000000
--- a/build/android/app/src/main/java/com/multicraft/game/helpers/AlertDialogHelper.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-MultiCraft
-Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
-Copyright (C) 2014-2020 ubulem, Bektur Mambetov
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 3.0 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-package com.multicraft.game.helpers;
-
-import android.graphics.drawable.Drawable;
-import android.widget.TextView;
-
-import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.app.AppCompatActivity;
-
-import com.multicraft.game.callbacks.DialogsCallback;
-
-
-public class AlertDialogHelper {
- private final AppCompatActivity activity;
- private DialogsCallback sCallback = null;
- private Drawable icon = null;
- private String title = null;
- private CharSequence message = null;
- private TextView tv = null;
- private String buttonPositive = null;
- private String buttonNegative = null;
- private String buttonNeutral = null;
-
- public AlertDialogHelper(AppCompatActivity activity) {
- this.activity = activity;
- }
-
- private Drawable getIcon() {
- return icon;
- }
-
- public void setIcon(Drawable icon) {
- this.icon = icon;
- }
-
- private String getTitle() {
- return title;
- }
-
- public void setTitle(String title) {
- this.title = title;
- }
-
- private CharSequence getMessage() {
- return message;
- }
-
- public void setMessage(CharSequence message) {
- this.message = message;
- }
-
- private TextView getTV() {
- return tv;
- }
-
- public void setTV(TextView tv) {
- this.tv = tv;
- }
-
- private String getButtonPositive() {
- return buttonPositive;
- }
-
- public void setButtonPositive(String buttonPositive) {
- this.buttonPositive = buttonPositive;
- }
-
- private String getButtonNegative() {
- return buttonNegative;
- }
-
- public void setButtonNegative(String buttonNegative) {
- this.buttonNegative = buttonNegative;
- }
-
- private String getButtonNeutral() {
- return buttonNeutral;
- }
-
- public void setButtonNeutral(String buttonNeutral) {
- this.buttonNeutral = buttonNeutral;
- }
-
- public void setListener(DialogsCallback callback) {
- sCallback = callback;
- }
-
- public void showAlert(final String source) {
- AlertDialog.Builder builder = new AlertDialog.Builder(activity);
- if (getIcon() != null) builder.setIcon(getIcon());
- if (getTitle() != null) builder.setTitle(getTitle());
- if (getMessage() != null) builder.setMessage(getMessage());
- if (getTV() != null) builder.setView(getTV());
- if (getButtonPositive() != null)
- builder.setPositiveButton(getButtonPositive(), (dialogInterface, i) -> {
- dialogInterface.dismiss();
- sCallback.onPositive(source);
- });
- if (getButtonNegative() != null)
- builder.setNegativeButton(getButtonNegative(), (dialogInterface, i) -> {
- dialogInterface.dismiss();
- sCallback.onNegative(source);
- });
- if (getButtonNeutral() != null)
- builder.setNeutralButton(getButtonNeutral(), (dialogInterface, i) -> {
- dialogInterface.dismiss();
- sCallback.onNeutral(source);
- });
- builder.setCancelable(false);
- final AlertDialog dialog = builder.create();
- if (!activity.isFinishing())
- dialog.show();
- }
-}
diff --git a/build/android/app/src/main/java/com/multicraft/game/helpers/ApiLevelHelper.java b/build/android/app/src/main/java/com/multicraft/game/helpers/ApiLevelHelper.java
deleted file mode 100644
index 6c982b67..00000000
--- a/build/android/app/src/main/java/com/multicraft/game/helpers/ApiLevelHelper.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-MultiCraft
-Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
-Copyright (C) 2014-2020 ubulem, Bektur Mambetov
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 3.0 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-package com.multicraft.game.helpers;
-
-import static android.os.Build.VERSION.SDK_INT;
-import static android.os.Build.VERSION_CODES.KITKAT;
-import static android.os.Build.VERSION_CODES.LOLLIPOP;
-import static android.os.Build.VERSION_CODES.O;
-import static android.os.Build.VERSION_CODES.Q;
-
-public class ApiLevelHelper {
- public static boolean isGreaterOrEqual(int versionCode) {
- return SDK_INT >= versionCode;
- }
-
- public static boolean isGreaterOrEqualKitkat() {
- return isGreaterOrEqual(KITKAT);
- }
-
- public static boolean isGreaterOrEqualLollipop() {
- return isGreaterOrEqual(LOLLIPOP);
- }
-
- public static boolean isGreaterOrEqualOreo() {
- return isGreaterOrEqual(O);
- }
-
- public static boolean isGreaterOrEqualQ() {
- return isGreaterOrEqual(Q);
- }
-}
diff --git a/build/android/app/src/main/java/com/multicraft/game/AdManager.java b/build/android/app/src/main/java/com/multicraft/game/helpers/ApiLevelHelper.kt
similarity index 53%
rename from build/android/app/src/main/java/com/multicraft/game/AdManager.java
rename to build/android/app/src/main/java/com/multicraft/game/helpers/ApiLevelHelper.kt
index 2564e6f4..bafbc4e1 100644
--- a/build/android/app/src/main/java/com/multicraft/game/AdManager.java
+++ b/build/android/app/src/main/java/com/multicraft/game/helpers/ApiLevelHelper.kt
@@ -1,7 +1,7 @@
/*
MultiCraft
-Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
-Copyright (C) 2014-2020 ubulem, Bektur Mambetov
+Copyright (C) 2014-2021 MoNTE48, Maksim Gamarnik
+Copyright (C) 2014-2021 ubulem, Bektur Mambetov
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
@@ -18,25 +18,26 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-package com.multicraft.game;
+package com.multicraft.game.helpers
-import android.app.Activity;
+import android.os.Build
+import android.os.Build.VERSION.SDK_INT
+import android.os.Build.VERSION_CODES.KITKAT
+import android.os.Build.VERSION_CODES.O
-class AdManager {
-
- static void initAd(final Activity activity, boolean consent) {
- // NDA code here
+object ApiLevelHelper {
+ private fun isGreaterOrEqual(versionCode: Int): Boolean {
+ return SDK_INT >= versionCode
}
- static void setAdsCallback(final Activity activity) {
- // NDA code here
- }
+ @JvmStatic
+ val isKitKat: Boolean
+ get() = isGreaterOrEqual(KITKAT)
- static void startAd(final Activity activity, boolean isFirstTime, boolean isShowNow) {
- // NDA code here
- }
+ val isMarshmallow: Boolean
+ get() = isGreaterOrEqual(Build.VERSION_CODES.M)
- static void stopAd() {
- // NDA code here
- }
+ @JvmStatic
+ val isOreo: Boolean
+ get() = isGreaterOrEqual(O)
}
diff --git a/build/android/app/src/main/java/com/multicraft/game/callbacks/DialogsCallback.java b/build/android/app/src/main/java/com/multicraft/game/helpers/Constants.kt
similarity index 66%
rename from build/android/app/src/main/java/com/multicraft/game/callbacks/DialogsCallback.java
rename to build/android/app/src/main/java/com/multicraft/game/helpers/Constants.kt
index 571434e1..bc2ef8bf 100644
--- a/build/android/app/src/main/java/com/multicraft/game/callbacks/DialogsCallback.java
+++ b/build/android/app/src/main/java/com/multicraft/game/helpers/Constants.kt
@@ -1,7 +1,7 @@
/*
MultiCraft
-Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
-Copyright (C) 2014-2020 ubulem, Bektur Mambetov
+Copyright (C) 2014-2021 MoNTE48, Maksim Gamarnik
+Copyright (C) 2014-2021 ubulem, Bektur Mambetov
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
@@ -18,12 +18,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-package com.multicraft.game.callbacks;
+package com.multicraft.game.helpers
-public interface DialogsCallback {
- void onPositive(String source);
+import com.multicraft.game.BuildConfig
- void onNegative(String source);
-
- void onNeutral(String source);
+object Constants {
+ const val REQUEST_CONNECTION = 104
+ const val NO_SPACE_LEFT = "ENOSPC"
+ const val FILES = "Files.zip"
+ const val versionName = BuildConfig.VERSION_NAME
}
diff --git a/build/android/app/src/main/java/com/multicraft/game/helpers/PermissionHelper.java b/build/android/app/src/main/java/com/multicraft/game/helpers/PermissionHelper.java
deleted file mode 100644
index d22686e3..00000000
--- a/build/android/app/src/main/java/com/multicraft/game/helpers/PermissionHelper.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-MultiCraft
-Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
-Copyright (C) 2014-2020 ubulem, Bektur Mambetov
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 3.0 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-package com.multicraft.game.helpers;
-
-import android.annotation.SuppressLint;
-
-import androidx.appcompat.app.AppCompatActivity;
-
-import com.multicraft.game.R;
-import com.multicraft.game.callbacks.CallBackListener;
-import com.tedpark.tedpermission.rx2.TedRx2Permission;
-
-import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
-
-public class PermissionHelper {
- private final AppCompatActivity activity;
- private CallBackListener listener;
- private PreferencesHelper pf;
-
- public PermissionHelper(AppCompatActivity activity) {
- this.activity = activity;
- }
-
- public void setListener(CallBackListener listener) {
- this.listener = listener;
- }
-
- public void askPermissions() {
- pf = PreferencesHelper.getInstance(activity);
- askStoragePermissions();
- }
-
- // permission block
- @SuppressLint("CheckResult")
- private void askStoragePermissions() {
- TedRx2Permission.with(activity)
- .setPermissions(WRITE_EXTERNAL_STORAGE)
- .request()
- .subscribe(tedPermissionResult -> {
- if (tedPermissionResult.isGranted()) {
- listener.onEvent(true);
- } else {
- if (TedRx2Permission.canRequestPermission(activity, WRITE_EXTERNAL_STORAGE))
- askStorageRationalePermissions();
- else askStorageWhenDoNotShow();
- }
- });
- }
-
- // storage permissions block
- @SuppressLint("CheckResult")
- private void askStorageRationalePermissions() {
- TedRx2Permission.with(activity)
- .setRationaleMessage(R.string.explain)
- .setDeniedMessage(R.string.denied)
- .setDeniedCloseButtonText(R.string.close_game)
- .setGotoSettingButtonText(R.string.settings)
- .setPermissions(WRITE_EXTERNAL_STORAGE)
- .request()
- .subscribe(tedPermissionResult -> {
- listener.onEvent(tedPermissionResult.isGranted());
- });
- }
-
- @SuppressLint("CheckResult")
- private void askStorageWhenDoNotShow() {
- TedRx2Permission.with(activity)
- .setDeniedMessage(R.string.denied)
- .setDeniedCloseButtonText(R.string.close_game)
- .setGotoSettingButtonText(R.string.settings)
- .setPermissions(WRITE_EXTERNAL_STORAGE)
- .request()
- .subscribe(tedPermissionResult -> {
- listener.onEvent(tedPermissionResult.isGranted());
- });
- }
-}
diff --git a/build/android/app/src/main/java/com/multicraft/game/helpers/PreferencesHelper.java b/build/android/app/src/main/java/com/multicraft/game/helpers/PreferencesHelper.java
index a40b188f..6766e0fa 100644
--- a/build/android/app/src/main/java/com/multicraft/game/helpers/PreferencesHelper.java
+++ b/build/android/app/src/main/java/com/multicraft/game/helpers/PreferencesHelper.java
@@ -1,7 +1,7 @@
/*
MultiCraft
-Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
-Copyright (C) 2014-2020 ubulem, Bektur Mambetov
+Copyright (C) 2014-2021 MoNTE48, Maksim Gamarnik
+Copyright (C) 2014-2021 ubulem, Bektur Mambetov
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
@@ -23,19 +23,10 @@ package com.multicraft.game.helpers;
import android.content.Context;
import android.content.SharedPreferences;
-import com.multicraft.game.RemoteSettings;
-
public class PreferencesHelper {
public static final String TAG_SHORTCUT_EXIST = "createShortcut";
public static final String TAG_BUILD_NUMBER = "buildNumber";
public static final String TAG_LAUNCH_TIMES = "launchTimes";
- public static final String TAG_CONSENT_ASKED = "consentAsked";
- public static final String TAG_COPY_OLD_WORLDS = "copyOldWorlds";
- public static final String IS_LOADED = "interstitialLoaded";
- public static final String RV_LOADED = "rewardedVideoLoaded";
- private static final String ADS_DELAY = "adsDelay";
- private static final String ADS_REPEAT = "adsRepeat";
- private static final String ADS_ENABLE = "adsEnable";
private static final String SETTINGS = "MultiCraftSettings";
private static PreferencesHelper instance;
@@ -59,22 +50,6 @@ public class PreferencesHelper {
return sharedPreferences.getBoolean(TAG_SHORTCUT_EXIST, false);
}
- public boolean isInterstitialLoaded() {
- return sharedPreferences.getBoolean(IS_LOADED, false);
- }
-
- public boolean isVideoLoaded() {
- return sharedPreferences.getBoolean(RV_LOADED, false);
- }
-
- public boolean isAskConsent() {
- return sharedPreferences.getBoolean(TAG_CONSENT_ASKED, true);
- }
-
- public boolean isWorldsCopied() {
- return sharedPreferences.getBoolean(TAG_COPY_OLD_WORLDS, false);
- }
-
public String getBuildNumber() {
return sharedPreferences.getString(TAG_BUILD_NUMBER, "0");
}
@@ -83,18 +58,6 @@ public class PreferencesHelper {
return sharedPreferences.getInt(TAG_LAUNCH_TIMES, 0);
}
- public int getAdsDelay() {
- return sharedPreferences.getInt(ADS_DELAY, 600);
- }
-
- public int getAdsRepeat() {
- return sharedPreferences.getInt(ADS_REPEAT, 900);
- }
-
- public boolean isAdsEnable() {
- return sharedPreferences.getBoolean(ADS_ENABLE, true);
- }
-
public void saveSettings(String tag, boolean bool) {
sharedPreferences.edit().putBoolean(tag, bool).apply();
}
@@ -106,12 +69,4 @@ public class PreferencesHelper {
public void saveSettings(String tag, int value) {
sharedPreferences.edit().putInt(tag, value).apply();
}
-
- public void saveAdsSettings(RemoteSettings remoteSettings) {
- int delay = remoteSettings.getAdsDelay();
- int repeat = remoteSettings.getAdsRepeat();
- if (delay != -1) saveSettings(ADS_DELAY, delay);
- if (repeat != -1) saveSettings(ADS_REPEAT, repeat);
- saveSettings(ADS_ENABLE, remoteSettings.isAdsEnabled());
- }
}
diff --git a/build/android/app/src/main/java/com/multicraft/game/helpers/Utilities.java b/build/android/app/src/main/java/com/multicraft/game/helpers/Utilities.java
deleted file mode 100644
index e493d569..00000000
--- a/build/android/app/src/main/java/com/multicraft/game/helpers/Utilities.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
-MultiCraft
-Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
-Copyright (C) 2014-2020 ubulem, Bektur Mambetov
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 3.0 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-package com.multicraft.game.helpers;
-
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.view.View;
-
-import com.bugsnag.android.Bugsnag;
-import com.multicraft.game.BuildConfig;
-import com.multicraft.game.MainActivity;
-import com.multicraft.game.R;
-
-import org.apache.commons.io.FileUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.List;
-
-import static com.multicraft.game.helpers.ApiLevelHelper.isGreaterOrEqualKitkat;
-import static com.multicraft.game.helpers.PreferencesHelper.TAG_SHORTCUT_EXIST;
-
-public class Utilities {
- private static final String appPackage = BuildConfig.APPLICATION_ID;
-
- private static boolean isInternetAvailable(String url) {
- try {
- HttpURLConnection urlc =
- (HttpURLConnection) new URL(url).openConnection();
- urlc.setRequestProperty("Connection", "close");
- urlc.setConnectTimeout(2000);
- urlc.connect();
- int ResponseCode = urlc.getResponseCode();
- return ResponseCode == HttpURLConnection.HTTP_NO_CONTENT ||
- ResponseCode == HttpURLConnection.HTTP_OK;
- } catch (IOException e) {
- return false;
- }
- }
-
- public static boolean isReachable() {
- return isInternetAvailable("http://clients3.google.com/generate_204") ||
- isInternetAvailable("http://servers.multicraft.world");
- }
-
- public static boolean deleteFiles(List files) {
- boolean result = true;
- for (String f : files) {
- File file = new File(f);
- if (file.exists()) {
- result = result && FileUtils.deleteQuietly(file);
- }
- }
- return result;
- }
-
- public static String getStoreUrl() {
- String store = "market://details?id=";
- return store + appPackage;
- }
-
- public static void makeFullScreen(Activity activity) {
- if (isGreaterOrEqualKitkat())
- activity.getWindow().getDecorView().setSystemUiVisibility(
- View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
- View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
- View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
- }
-
- public static Drawable getIcon(Activity activity) {
- try {
- return activity.getPackageManager().getApplicationIcon(activity.getPackageName());
- } catch (PackageManager.NameNotFoundException e) {
- Bugsnag.notify(e);
- return activity.getResources().getDrawable(R.mipmap.ic_launcher);
- }
- }
-
- public static void addShortcut(Activity activity) {
- ActivityManager activityManager =
- (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
- int size = 0;
- if (activityManager != null)
- size = activityManager.getLauncherLargeIconSize();
- Bitmap shortcutIconBitmap = ((BitmapDrawable) getIcon(activity)).getBitmap();
- if (shortcutIconBitmap.getWidth() < size)
- shortcutIconBitmap = Bitmap.createScaledBitmap(shortcutIconBitmap, size, size, true);
- PreferencesHelper.getInstance(activity).saveSettings(TAG_SHORTCUT_EXIST, true);
- Intent shortcutIntent = new Intent(activity, MainActivity.class);
- shortcutIntent.setAction(Intent.ACTION_MAIN);
- Intent addIntent = new Intent();
- addIntent.putExtra("duplicate", false);
- addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
- addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, activity.getResources().getString(R.string.app_name));
- addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, shortcutIconBitmap);
- addIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
- activity.sendBroadcast(addIntent);
- }
-}
diff --git a/build/android/app/src/main/java/com/multicraft/game/helpers/Utilities.kt b/build/android/app/src/main/java/com/multicraft/game/helpers/Utilities.kt
new file mode 100644
index 00000000..45d3fdad
--- /dev/null
+++ b/build/android/app/src/main/java/com/multicraft/game/helpers/Utilities.kt
@@ -0,0 +1,163 @@
+/*
+MultiCraft
+Copyright (C) 2014-2021 MoNTE48, Maksim Gamarnik
+Copyright (C) 2014-2021 ubulem, Bektur Mambetov
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3.0 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+package com.multicraft.game.helpers
+
+import android.annotation.SuppressLint
+import android.app.Activity
+import android.app.ActivityManager
+import android.app.AlarmManager
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.graphics.Bitmap
+import android.graphics.drawable.BitmapDrawable
+import android.graphics.drawable.Drawable
+import android.net.ConnectivityManager
+import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
+import android.view.View
+import android.view.Window
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.ContextCompat
+import androidx.core.view.WindowCompat
+import androidx.core.view.WindowInsetsCompat.Type.navigationBars
+import androidx.core.view.WindowInsetsCompat.Type.statusBars
+import androidx.core.view.WindowInsetsControllerCompat
+import androidx.core.view.WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
+import com.multicraft.game.MainActivity
+import com.multicraft.game.R
+import com.multicraft.game.helpers.ApiLevelHelper.isKitKat
+import com.multicraft.game.helpers.ApiLevelHelper.isMarshmallow
+import com.multicraft.game.helpers.ApiLevelHelper.isOreo
+import com.multicraft.game.helpers.PreferencesHelper.TAG_SHORTCUT_EXIST
+import com.multicraft.game.helpers.PreferencesHelper.getInstance
+import java.io.File
+import java.io.InputStream
+import kotlin.math.roundToInt
+import kotlin.system.exitProcess
+
+@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
+object Utilities {
+ @JvmStatic
+ fun deleteFiles(files: List, path: File) {
+ for (f in files) {
+ val file = File(path, f)
+ if (file.exists()) file.deleteRecursively()
+ }
+ }
+
+ @JvmStatic
+ fun deleteFiles(files: List) {
+ for (file in files)
+ if (file.exists()) file.deleteRecursively()
+ }
+
+ @JvmStatic
+ fun getTotalMem(context: Context): Float {
+ val actManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
+ val memInfo = ActivityManager.MemoryInfo()
+ actManager.getMemoryInfo(memInfo)
+ var memory = memInfo.totalMem * 1.0f / (1024 * 1024 * 1024)
+ memory = (memory * 100).roundToInt() / 100.0f
+ return memory
+ }
+
+ @JvmStatic
+ fun makeFullScreen(window: Window) {
+ if (isKitKat) @Suppress("DEPRECATION") {
+ val decor = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
+ View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
+ View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ window.decorView.systemUiVisibility = decor
+ } else {
+ WindowCompat.setDecorFitsSystemWindows(window, false)
+ WindowInsetsControllerCompat(window, window.decorView).let { controller ->
+ controller.hide(statusBars() or navigationBars())
+ controller.systemBarsBehavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
+ }
+ }
+ }
+
+ @JvmStatic
+ fun getIcon(activity: Activity): Drawable? {
+ return try {
+ activity.packageManager.getApplicationIcon(activity.packageName)
+ } catch (e: PackageManager.NameNotFoundException) {
+ ContextCompat.getDrawable(activity, R.mipmap.ic_launcher)
+ }
+ }
+
+ @JvmStatic
+ @Suppress("DEPRECATION")
+ fun addShortcut(activity: AppCompatActivity) {
+ if (isOreo) return
+ val activityManager = activity.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
+ val size = activityManager.launcherLargeIconSize
+ var shortcutIconBitmap = (getIcon(activity) as BitmapDrawable).bitmap
+ if (shortcutIconBitmap.width != size || shortcutIconBitmap.height != size)
+ shortcutIconBitmap = Bitmap.createScaledBitmap(shortcutIconBitmap, size, size, true)
+ val shortcutIntent = Intent(activity, MainActivity::class.java)
+ shortcutIntent.action = Intent.ACTION_MAIN
+ val addIntent = Intent()
+ addIntent.putExtra("duplicate", false)
+ addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent)
+ addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, R.string.app_name)
+ addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, shortcutIconBitmap)
+ addIntent.action = "com.android.launcher.action.INSTALL_SHORTCUT"
+ activity.applicationContext.sendBroadcast(addIntent)
+ // save preference
+ getInstance(activity).saveSettings(TAG_SHORTCUT_EXIST, true)
+ }
+
+ @JvmStatic
+ @SuppressLint("UnspecifiedImmutableFlag")
+ fun finishApp(restart: Boolean, activity: Activity) {
+ if (restart) {
+ val intent = Intent(activity, activity::class.java)
+ val mPendingIntentId = 1337
+ val mgr = activity.getSystemService(Context.ALARM_SERVICE) as AlarmManager
+ mgr.set(
+ AlarmManager.RTC, System.currentTimeMillis(), PendingIntent.getActivity(
+ activity, mPendingIntentId, intent, PendingIntent.FLAG_CANCEL_CURRENT
+ )
+ )
+ }
+ exitProcess(0)
+ }
+
+ @JvmStatic
+ fun File.copyInputStreamToFile(inputStream: InputStream) {
+ this.outputStream().use { fileOut -> inputStream.copyTo(fileOut) }
+ }
+
+ @JvmStatic
+ fun isConnected(context: Context): Boolean {
+ val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
+ if (isMarshmallow) {
+ val activeNetwork = cm.activeNetwork ?: return false
+ val capabilities = cm.getNetworkCapabilities(activeNetwork) ?: return false
+ return capabilities.hasCapability(NET_CAPABILITY_VALIDATED)
+ } else @Suppress("DEPRECATION") {
+ val activeNetworkInfo = cm.activeNetworkInfo ?: return false
+ return activeNetworkInfo.isConnected
+ }
+ }
+}
diff --git a/build/android/app/src/main/java/com/multicraft/game/helpers/VersionManagerHelper.java b/build/android/app/src/main/java/com/multicraft/game/helpers/VersionManagerHelper.java
deleted file mode 100644
index 9d176304..00000000
--- a/build/android/app/src/main/java/com/multicraft/game/helpers/VersionManagerHelper.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
-MultiCraft
-Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik
-Copyright (C) 2014-2020 ubulem, Bektur Mambetov
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 3.0 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-package com.multicraft.game.helpers;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.text.Editable;
-import android.text.Html;
-
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.preference.PreferenceManager;
-
-import com.bugsnag.android.Bugsnag;
-import com.multicraft.game.BuildConfig;
-import com.multicraft.game.RemoteSettings;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONTokener;
-import org.xml.sax.XMLReader;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
-import java.util.Locale;
-import java.util.concurrent.TimeUnit;
-
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.Response;
-
-import static com.multicraft.game.MainActivity.UPDATE_LINK;
-import static com.multicraft.game.helpers.Utilities.getStoreUrl;
-
-public class VersionManagerHelper {
- private static final String JSON_VERSION_CODE = "version_code";
- private static final String JSON_VERSION_CODE_BAD = "version_code_bad";
- private static final String JSON_PACKAGE = "package";
- private static final String JSON_CONTENT_RU = "content_ru";
- private static final String JSON_CONTENT_EN = "content_en";
- private static final String JSON_ADS_DELAY = "ads_delay";
- private static final String JSON_ADS_REPEAT = "ads_repeat";
- private static final String JSON_ADS_ENABLE = "ads_enable";
- private final CustomTagHandler customTagHandler;
- private final String PREF_REMINDER_TIME = "w.reminder.time";
- private final AppCompatActivity activity;
- private final int versionCode = BuildConfig.VERSION_CODE;
- private String message, updateUrl;
-
- public VersionManagerHelper(AppCompatActivity act) {
- this.activity = act;
- this.customTagHandler = new CustomTagHandler();
- }
-
- public boolean isCheckVersion() {
- long currentTimeStamp = Calendar.getInstance().getTimeInMillis();
- long reminderTimeStamp = getReminderTime();
- return currentTimeStamp > reminderTimeStamp;
- }
-
- private boolean isBadVersion(List badVersions) {
- return badVersions.contains(versionCode);
- }
-
- private List convertToList(JSONArray badVersions) throws JSONException {
- List badVersionList = new ArrayList<>();
- if (badVersions != null) {
- for (int i = 0; i < badVersions.length(); i++)
- badVersionList.add(badVersions.getInt(i));
- }
- return badVersionList;
- }
-
- private RemoteSettings parseJson(String result) throws JSONException {
- RemoteSettings remoteSettings = new RemoteSettings();
- PreferencesHelper pf = PreferencesHelper.getInstance(activity);
- if (!result.startsWith("{")) // for response who append with unknown char
- result = result.substring(1);
- String mResult = result;
- // json format from server:
- JSONObject json = new JSONObject(new JSONTokener(mResult));
- remoteSettings.setVersionCode(json.getInt(JSON_VERSION_CODE));
- remoteSettings.setBadVersionCodes(convertToList(json.getJSONArray(JSON_VERSION_CODE_BAD)));
- String lang = Locale.getDefault().getLanguage();
- String content = lang.equals("ru") ? JSON_CONTENT_RU : JSON_CONTENT_EN;
- remoteSettings.setContent(json.getString(content));
- setMessage(remoteSettings.getContent());
- remoteSettings.setPackageName(json.getString(JSON_PACKAGE));
- setUpdateUrl("market://details?id=" + remoteSettings.getPackageName());
- remoteSettings.setAdsDelay(json.getInt(JSON_ADS_DELAY));
- remoteSettings.setAdsRepeat(json.getInt(JSON_ADS_REPEAT));
- remoteSettings.setAdsEnabled(json.getBoolean(JSON_ADS_ENABLE));
- pf.saveAdsSettings(remoteSettings);
- return remoteSettings;
- }
-
- public boolean isShow(String result) {
- if (result.equals("{}")) return false;
- RemoteSettings remoteSettings;
- try {
- remoteSettings = parseJson(result);
- } catch (JSONException e) {
- return false;
- }
- return (versionCode < remoteSettings.getVersionCode()) ||
- isBadVersion(remoteSettings.getBadVersionCodes());
- }
-
- public String getJson() {
- OkHttpClient client = new OkHttpClient.Builder()
- .callTimeout(3000, TimeUnit.MILLISECONDS)
- .build();
- Request request = new Request.Builder()
- .url(UPDATE_LINK)
- .build();
- try {
- Response response = client.newCall(request).execute();
- return response.body().string();
- } catch (IOException | NullPointerException e) {
- // nothing
- }
- return "{}";
- }
-
- public String getMessage() {
- String defaultMessage = "What's new?";
- return message != null ? message : defaultMessage;
- }
-
- private void setMessage(String message) {
- this.message = message;
- }
-
- public String getUpdateUrl() {
- return updateUrl != null ? updateUrl : getStoreUrl();
- }
-
- private void setUpdateUrl(String updateUrl) {
- this.updateUrl = updateUrl;
- }
-
- public void updateNow(String url) {
- if (url != null) {
- try {
- Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
- activity.startActivity(intent);
- } catch (Exception e) {
- Bugsnag.notify(e);
- }
- }
- }
-
- public void remindMeLater() {
- Calendar c = Calendar.getInstance();
- c.add(Calendar.MINUTE, 1);
- long reminderTimeStamp = c.getTimeInMillis();
- setReminderTime(reminderTimeStamp);
- }
-
- private long getReminderTime() {
- return PreferenceManager.getDefaultSharedPreferences(activity).getLong(
- PREF_REMINDER_TIME, 0);
- }
-
- private void setReminderTime(long reminderTimeStamp) {
- PreferenceManager.getDefaultSharedPreferences(activity).edit().putLong(
- PREF_REMINDER_TIME, reminderTimeStamp).apply();
- }
-
- public CustomTagHandler getCustomTagHandler() {
- return customTagHandler;
- }
-
- private static class CustomTagHandler implements Html.TagHandler {
- @Override
- public void handleTag(boolean opening, String tag, Editable output,
- XMLReader xmlReader) {
- // you may add more tag handler which are not supported by android here
- if ("li".equals(tag)) {
- if (opening)
- output.append(" \u2022 ");
- else
- output.append("\n");
- }
- }
- }
-}
diff --git a/build/android/app/src/main/res/drawable/background.png b/build/android/app/src/main/res/drawable/background.png
index 55afbb6f..84f1fd4c 100644
Binary files a/build/android/app/src/main/res/drawable/background.png and b/build/android/app/src/main/res/drawable/background.png differ
diff --git a/build/android/app/src/main/res/drawable/custom_dialog_rounded.xml b/build/android/app/src/main/res/drawable/custom_dialog_rounded.xml
deleted file mode 100644
index f5e0ff00..00000000
--- a/build/android/app/src/main/res/drawable/custom_dialog_rounded.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
diff --git a/build/android/app/src/main/res/drawable/custom_edittext_rounded.xml b/build/android/app/src/main/res/drawable/custom_edittext_rounded.xml
deleted file mode 100644
index d72c5785..00000000
--- a/build/android/app/src/main/res/drawable/custom_edittext_rounded.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
- -
-
-
-
-
-
-
-
-
diff --git a/build/android/app/src/main/res/drawable/ic_launcher_background.xml b/build/android/app/src/main/res/drawable/ic_launcher_background.xml
deleted file mode 100644
index fe5102ec..00000000
--- a/build/android/app/src/main/res/drawable/ic_launcher_background.xml
+++ /dev/null
@@ -1,170 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/build/android/app/src/main/res/layout/activity_main.xml b/build/android/app/src/main/res/layout/activity_main.xml
index 1f364d80..24dd23e1 100644
--- a/build/android/app/src/main/res/layout/activity_main.xml
+++ b/build/android/app/src/main/res/layout/activity_main.xml
@@ -3,8 +3,8 @@
android:layout_height="match_parent">
+ android:indeterminate="true" />
+ android:textColor="@color/not_white"
+ android:textSize="14sp" />
diff --git a/build/android/app/src/main/res/layout/input_text.xml b/build/android/app/src/main/res/layout/input_text.xml
new file mode 100644
index 00000000..a27bf6e2
--- /dev/null
+++ b/build/android/app/src/main/res/layout/input_text.xml
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/build/android/app/src/main/res/layout/rate_dialog.xml b/build/android/app/src/main/res/layout/rate_dialog.xml
deleted file mode 100644
index e0515207..00000000
--- a/build/android/app/src/main/res/layout/rate_dialog.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/build/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/build/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
index 110fbe9e..4f0acc75 100644
--- a/build/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/build/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/build/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/build/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
index 110fbe9e..4f0acc75 100644
--- a/build/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ b/build/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/build/android/app/src/main/res/mipmap/ic_launcher.png b/build/android/app/src/main/res/mipmap/ic_launcher.png
index 42c24d58..e9db08b5 100644
Binary files a/build/android/app/src/main/res/mipmap/ic_launcher.png and b/build/android/app/src/main/res/mipmap/ic_launcher.png differ
diff --git a/build/android/app/src/main/res/values-ru/strings.xml b/build/android/app/src/main/res/values-ru/strings.xml
index 139e2f56..4b4a75d6 100644
--- a/build/android/app/src/main/res/values-ru/strings.xml
+++ b/build/android/app/src/main/res/values-ru/strings.xml
@@ -5,38 +5,20 @@
Подготовка к запуску…
Загрузка…
Загрузка… %d%%
- Загрузка новой версии…
- Загрузка новой версии… %d%%
Загрузка MultiCraft
Осталось меньше минуты…
- Произошла ошибка, игра будет перезапущена автоматически
+ Память устройства недоступна для записи
+ Произошла ошибка %s\nИгра будет перезапущена автоматически
Недостаточно места для записи файлов игры, пожалуйста освободите место в памяти
-
- Разрешение на запись необходимо для распаковки текстур и игровых файлов.
- Доступ к местоположению обеспечивает Вам лучшее взаимодействие с игрой
- Закрыть игру
- Настройки
- Вы не можете играть в MultiCraft без разрешения на запись.\nПожалуйста, включите его в [Настройки] -> [Разрешения]>
-
-
- Оцените MultiCraft!
- Поделитесь впечатлениями
- ОЦЕНИТЬ
- Нам жаль, что Вам не понравилась игра!
- Пожалуйста, оставьте отзыв для нас. Спасибо!
-
-
- Доступна Новая Версия!
- Игнорировать
- Позже
- Обновить
+ Введите Текст
+ Пароль
+ Готово
- Для полноценной игры, MultiCraft требует подключение к интернету.\nВ противном случае невозможно обновление игры, а так же недоступен мультиплеер!
+ Нет Интернет Подключения!
+ Для полноценной игры, MultiCraft требует подключение к Интернету.\nВ противном случае вам будет недоступно Обновление игры и режим Мультиплеера!
3G/4G
-
-
- Удалить старую версию MultiCraft?
+ Игнорировать
diff --git a/build/android/app/src/main/res/values/colors.xml b/build/android/app/src/main/res/values/colors.xml
new file mode 100644
index 00000000..280fe7bd
--- /dev/null
+++ b/build/android/app/src/main/res/values/colors.xml
@@ -0,0 +1,5 @@
+
+
+ #008c80
+ #fefefe
+
diff --git a/build/android/app/src/main/res/values/strings.xml b/build/android/app/src/main/res/values/strings.xml
index 4424f45d..0b3ba18c 100644
--- a/build/android/app/src/main/res/values/strings.xml
+++ b/build/android/app/src/main/res/values/strings.xml
@@ -7,46 +7,22 @@
Preparing to launch…
Loading…
Loading… %d%%
- Downloading new version…
- Downloading new version… %d%%
Loading MultiCraft
Less than 1 minute…
- Unexpected issue, the game will be restarted automatically
+ Bad disk space state
+ Unexpected error: \"%s\"\nThe game will be restarted automatically
No space left for game files, please free space in the memory
OK
-
- Storage permissions is necessary to unpack textures and game data.
- Location permission provide you better interaction with game
- Close game
- App settings
- You cannot play MultiCraft without storage permission.\nPlease turn on it at [Settings] -> [Permissions]>
-
-
- Please, rate MultiCraft!
- Describe your experience
- SUBMIT
- We are sorry that you did not like the game!
- Please leave a review for us. Thank you!
-
-
- New Version Available!
- Update
- Later
- Ignore
+ Text Input
+ Password
+ Done
- MultiCraft requires an internet connection to use all game features.\nOtherwise, you will not get updates and multiplayer will be not available!
+ No Internet Connection!
+ MultiCraft requires an Internet connection to use all game features.\nOtherwise, you will not get Updates and Multiplayer mode will be not available!
Wi-Fi
Mobile Data
-
-
- Uninstall an old version of MultiCraft?
-
-
- We care about your privacy and data security. We keep this app free by showing ads.\nCan we continue to use your data to tailor ads for you?\n\nOur partners will collect data and use a unique identifier on your device to show you ads. By agreeing, you confirm that you are 16 years old. You can learn how we and our partners collect and use data on Privacy Policy.
- Yes, I allow
- No
-
+ Ignore
diff --git a/build/android/app/src/main/res/values/styles.xml b/build/android/app/src/main/res/values/styles.xml
index 495f63ed..c99668d1 100644
--- a/build/android/app/src/main/res/values/styles.xml
+++ b/build/android/app/src/main/res/values/styles.xml
@@ -1,23 +1,13 @@
-
-
-
-
-
diff --git a/build/android/app/src/main/res/xml/network_security_config.xml b/build/android/app/src/main/res/xml/network_security_config.xml
deleted file mode 100644
index 8501de96..00000000
--- a/build/android/app/src/main/res/xml/network_security_config.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
- 127.0.0.1
-
-
diff --git a/build/android/build.gradle b/build/android/build.gradle
index 86f2c5ed..5abc0952 100644
--- a/build/android/build.gradle
+++ b/build/android/build.gradle
@@ -7,9 +7,8 @@ buildscript {
maven { url 'https://plugins.gradle.org/m2/' }
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.2.1'
- //noinspection GradleDynamicVersion
- /*classpath 'com.bugsnag:bugsnag-android-gradle-plugin:5.+'*/
+ classpath 'com.android.tools.build:gradle:4.2.2'
+ classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.20'
classpath 'de.undercouch:gradle-download-task:4.1.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/build/android/gradle.properties b/build/android/gradle.properties
index 53b475cf..16ac31d7 100644
--- a/build/android/gradle.properties
+++ b/build/android/gradle.properties
@@ -1,11 +1,19 @@
+# Project-wide Gradle settings.
<#if isLowMemory>
-org.gradle.jvmargs=-Xmx4G -XX:MaxPermSize=2G -XX:+HeapDumpOnOutOfMemoryError
+org.gradle.jvmargs=-Xmx4G -XX:MaxPermSize=2G
<#else>
-org.gradle.jvmargs=-Xmx16G -XX:MaxPermSize=8G -XX:+HeapDumpOnOutOfMemoryError
+org.gradle.jvmargs=-Xmx16G -XX:MaxPermSize=8G
#if>
+org.gradle.jvmargs+=-XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.parallel.threads=8
org.gradle.configureondemand=true
-android.enableJetifier=true
+# AndroidX package structure
android.useAndroidX=true
+# Automatically convert third-party libraries to use AndroidX
+android.enableJetifier=true
+# Kotlin code style for this project
+kotlin.code.style=official
+# R8 Mode
+android.enableR8.fullMode=true
diff --git a/build/android/gradle/wrapper/gradle-wrapper.properties b/build/android/gradle/wrapper/gradle-wrapper.properties
index 8ab187ef..13037ce1 100644
--- a/build/android/gradle/wrapper/gradle-wrapper.properties
+++ b/build/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Sun May 09 00:39:14 CEST 2021
+#Sat Jul 10 17:16:36 EEST 2021
distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
diff --git a/build/android/native/build.gradle b/build/android/native/build.gradle
index 4a343447..66bfb5fd 100644
--- a/build/android/native/build.gradle
+++ b/build/android/native/build.gradle
@@ -2,13 +2,12 @@ apply plugin: 'com.android.library'
apply plugin: 'de.undercouch.download'
android {
- compileSdkVersion 29
+ compileSdkVersion 30
buildToolsVersion '30.0.3'
ndkVersion '22.1.7171670'
defaultConfig {
- minSdkVersion 16
- //noinspection OldTargetApi
- targetSdkVersion 29
+ minSdkVersion 19
+ targetSdkVersion 30
externalNativeBuild {
ndkBuild {
arguments '-j' + Runtime.getRuntime().availableProcessors(),
@@ -28,7 +27,7 @@ android {
abi {
enable true
reset()
- include 'armeabi-v7a', 'arm64-v8a'//, 'x86'
+ include 'armeabi-v7a', 'arm64-v8a'
}
}
diff --git a/build/android/native/jni/Application.mk b/build/android/native/jni/Application.mk
index 8b46e6d1..91e26f30 100644
--- a/build/android/native/jni/Application.mk
+++ b/build/android/native/jni/Application.mk
@@ -22,7 +22,7 @@ endif
APP_CPPFLAGS += -fexceptions #-Werror=shorten-64-to-32
# Silence Irrlicht warnings. Comment out with real debugging!
-APP_CPPFLAGS += -Wno-deprecated-declarations -Wno-inconsistent-missing-override
+APP_CPPFLAGS += -Wno-deprecated-declarations -Wno-inconsistent-missing-override -Wno-implicit-int-float-conversion
APP_CFLAGS := $(APP_CPPFLAGS)
APP_CXXFLAGS := $(APP_CPPFLAGS) -frtti -std=gnu++17
@@ -32,5 +32,3 @@ APP_LDFLAGS := -Wl,--gc-sections,--icf=all
else
APP_LDFLAGS :=
endif
-
-APP_LDFLAGS += -fuse-ld=lld