Android: spaces => tabs

This commit is contained in:
MoNTE48 2020-10-04 20:16:21 +02:00
parent 9b82dbd2cc
commit f45bba820a
38 changed files with 1716 additions and 1724 deletions

View File

@ -1,78 +1,78 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
package="com.multicraft.game" package="com.multicraft.game"
android:installLocation="auto"> android:installLocation="auto">
<uses-permission <uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:node="replace" /> tools:node="replace" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" /> <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-feature <uses-feature
android:name="android.hardware.touchscreen" android:name="android.hardware.touchscreen"
android:required="false" /> android:required="false" />
<uses-feature <uses-feature
android:name="android.hardware.wifi" android:name="android.hardware.wifi"
android:required="false" /> android:required="false" />
<supports-screens <supports-screens
android:largeScreens="true" android:largeScreens="true"
android:xlargeScreens="true" /> android:xlargeScreens="true" />
<application <application
android:name=".MyApplication" android:name=".MyApplication"
android:allowBackup="true" android:allowBackup="true"
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config" android:networkSecurityConfig="@xml/network_security_config"
android:requestLegacyExternalStorage="true" android:requestLegacyExternalStorage="true"
android:resizeableActivity="false" android:resizeableActivity="false"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
tools:ignore="UnusedAttribute"> tools:ignore="UnusedAttribute">
<meta-data <meta-data
android:name="android.max_aspect" android:name="android.max_aspect"
android:value="3.0" /> android:value="3.0" />
<activity <activity
android:name="com.multicraft.game.MainActivity" android:name="com.multicraft.game.MainActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize" android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:maxAspectRatio="3.0" android:maxAspectRatio="3.0"
android:screenOrientation="sensorLandscape" android:screenOrientation="sensorLandscape"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
android:name="com.multicraft.game.GameActivity" android:name="com.multicraft.game.GameActivity"
android:configChanges="orientation|keyboard|keyboardHidden|navigation|screenSize|smallestScreenSize" android:configChanges="orientation|keyboard|keyboardHidden|navigation|screenSize|smallestScreenSize"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:launchMode="singleTask" android:launchMode="singleTask"
android:maxAspectRatio="3.0" android:maxAspectRatio="3.0"
android:screenOrientation="sensorLandscape" android:screenOrientation="sensorLandscape"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<meta-data <meta-data
android:name="android.app.lib_name" android:name="android.app.lib_name"
android:value="MultiCraft" /> android:value="MultiCraft" />
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
</intent-filter> </intent-filter>
</activity> </activity>
<service <service
android:name="com.multicraft.game.UnzipService" android:name="com.multicraft.game.UnzipService"
android:enabled="true" android:enabled="true"
android:exported="false" /> android:exported="false" />
</application> </application>
</manifest> </manifest>

View File

@ -4,15 +4,15 @@ import android.app.Application;
import android.util.Log; import android.util.Log;
public class Bugsnag { public class Bugsnag {
public static void notify(Throwable e) { public static void notify(Throwable e) {
Log.getStackTraceString(e); Log.getStackTraceString(e);
} }
public static void leaveBreadcrumb(String s) { public static void leaveBreadcrumb(String s) {
Log.d("Bugsnag", s); Log.d("Bugsnag", s);
} }
public static void start(Application application) { public static void start(Application application) {
Log.d("Bugsnag", "Bugsnag initialized"); Log.d("Bugsnag", "Bugsnag initialized");
} }
} }

View File

@ -24,19 +24,19 @@ import android.app.Activity;
class AdManager { class AdManager {
static void initAd(final Activity activity, boolean consent) { static void initAd(final Activity activity, boolean consent) {
// NDA code here // NDA code here
} }
static void setAdsCallback(final Activity activity) { static void setAdsCallback(final Activity activity) {
// NDA code here // NDA code here
} }
static void startAd(final Activity activity, boolean isFirstTime, boolean isShowNow) { static void startAd(final Activity activity, boolean isFirstTime, boolean isShowNow) {
// NDA code here // NDA code here
} }
static void stopAd() { static void stopAd() {
// NDA code here // NDA code here
} }
} }

View File

@ -27,17 +27,17 @@ import android.view.inputmethod.InputMethodManager;
import androidx.appcompat.widget.AppCompatEditText; import androidx.appcompat.widget.AppCompatEditText;
public class CustomEditText extends AppCompatEditText { public class CustomEditText extends AppCompatEditText {
public CustomEditText(Context context) { public CustomEditText(Context context) {
super(context); super(context);
} }
@Override @Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) { public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) { if (keyCode == KeyEvent.KEYCODE_BACK) {
InputMethodManager mgr = (InputMethodManager) InputMethodManager mgr = (InputMethodManager)
getContext().getSystemService(Context.INPUT_METHOD_SERVICE); getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(this.getWindowToken(), 0); mgr.hideSoftInputFromWindow(this.getWindowToken(), 0);
} }
return false; return false;
} }
} }

View File

@ -47,182 +47,181 @@ import static com.multicraft.game.AdManager.initAd;
import static com.multicraft.game.AdManager.setAdsCallback; import static com.multicraft.game.AdManager.setAdsCallback;
import static com.multicraft.game.AdManager.startAd; import static com.multicraft.game.AdManager.startAd;
import static com.multicraft.game.AdManager.stopAd; import static com.multicraft.game.AdManager.stopAd;
import static com.multicraft.game.helpers.PreferencesHelper.TAG_BUILD_NUMBER;
import static com.multicraft.game.helpers.PreferencesHelper.getInstance; import static com.multicraft.game.helpers.PreferencesHelper.getInstance;
import static com.multicraft.game.helpers.Utilities.makeFullScreen; import static com.multicraft.game.helpers.Utilities.makeFullScreen;
public class GameActivity extends NativeActivity { public class GameActivity extends NativeActivity {
static { static {
try { try {
System.loadLibrary("MultiCraft"); System.loadLibrary("MultiCraft");
} catch (UnsatisfiedLinkError | OutOfMemoryError e) { } catch (UnsatisfiedLinkError | OutOfMemoryError e) {
Bugsnag.notify(e); Bugsnag.notify(e);
System.exit(0); System.exit(0);
} catch (IllegalArgumentException i) { } catch (IllegalArgumentException i) {
Bugsnag.notify(i); Bugsnag.notify(i);
System.exit(0); System.exit(0);
} catch (Error | Exception e) { } catch (Error | Exception e) {
Bugsnag.notify(e); Bugsnag.notify(e);
System.exit(0); System.exit(0);
} }
} }
private int messageReturnCode = -1; private int messageReturnCode = -1;
private String messageReturnValue = ""; private String messageReturnValue = "";
private int height, width; private int height, width;
private boolean consent, isMultiPlayer; private boolean consent, isMultiPlayer;
private PreferencesHelper pf; private PreferencesHelper pf;
private Disposable adInitSub; private Disposable adInitSub;
private boolean hasKeyboard; private boolean hasKeyboard;
public static native void putMessageBoxResult(String text); public static native void putMessageBoxResult(String text);
public static native void pauseGame(); public static native void pauseGame();
public static native void keyboardEvent(boolean keyboard); public static native void keyboardEvent(boolean keyboard);
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Bundle bundle = getIntent().getExtras(); Bundle bundle = getIntent().getExtras();
Resources resources = getResources(); Resources resources = getResources();
height = bundle != null ? bundle.getInt("height", 0) : resources.getDisplayMetrics().heightPixels; height = bundle != null ? bundle.getInt("height", 0) : resources.getDisplayMetrics().heightPixels;
width = bundle != null ? bundle.getInt("width", 0) : resources.getDisplayMetrics().widthPixels; width = bundle != null ? bundle.getInt("width", 0) : resources.getDisplayMetrics().widthPixels;
consent = bundle == null || bundle.getBoolean("consent", true); consent = bundle == null || bundle.getBoolean("consent", true);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
hasKeyboard = !(resources.getConfiguration().hardKeyboardHidden == KEYBOARD_QWERTY); hasKeyboard = !(resources.getConfiguration().hardKeyboardHidden == KEYBOARD_QWERTY);
keyboardEvent(hasKeyboard); keyboardEvent(hasKeyboard);
pf = getInstance(this); pf = getInstance(this);
if (pf.isAdsEnable()) { if (pf.isAdsEnable()) {
adInitSub = Completable.fromAction(() -> initAd(this, consent)) adInitSub = Completable.fromAction(() -> initAd(this, consent))
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(() -> setAdsCallback(this)); .subscribe(() -> setAdsCallback(this));
} }
} }
@Override @Override
public void onWindowFocusChanged(boolean hasFocus) { public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus); super.onWindowFocusChanged(hasFocus);
if (hasFocus) if (hasFocus)
makeFullScreen(this); makeFullScreen(this);
} }
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
makeFullScreen(this); makeFullScreen(this);
} }
@Override @Override
public void onBackPressed() { public void onBackPressed() {
} }
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
adInitSub.dispose(); adInitSub.dispose();
} }
public void showDialog(String acceptButton, String hint, String current, int editType) { public void showDialog(String acceptButton, String hint, String current, int editType) {
runOnUiThread(() -> showDialogUI(hint, current, editType)); runOnUiThread(() -> showDialogUI(hint, current, editType));
} }
@Override @Override
protected void onPause() { protected void onPause() {
super.onPause(); super.onPause();
pauseGame(); pauseGame();
} }
@Override @Override
public void onConfigurationChanged(Configuration newConfig) { public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig); super.onConfigurationChanged(newConfig);
boolean statusKeyboard = !(getResources().getConfiguration().hardKeyboardHidden == KEYBOARD_QWERTY); boolean statusKeyboard = !(getResources().getConfiguration().hardKeyboardHidden == KEYBOARD_QWERTY);
if (hasKeyboard != statusKeyboard) { if (hasKeyboard != statusKeyboard) {
hasKeyboard = statusKeyboard; hasKeyboard = statusKeyboard;
keyboardEvent(hasKeyboard); keyboardEvent(hasKeyboard);
} }
} }
private void showDialogUI(String hint, String current, int editType) { private void showDialogUI(String hint, String current, int editType) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this); final AlertDialog.Builder builder = new AlertDialog.Builder(this);
EditText editText = new CustomEditText(this); EditText editText = new CustomEditText(this);
builder.setView(editText); builder.setView(editText);
AlertDialog alertDialog = builder.create(); AlertDialog alertDialog = builder.create();
editText.requestFocus(); editText.requestFocus();
editText.setHint(hint); editText.setHint(hint);
editText.setText(current); editText.setText(current);
final InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); final InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,
InputMethodManager.HIDE_IMPLICIT_ONLY); InputMethodManager.HIDE_IMPLICIT_ONLY);
if (editType == 1) if (editType == 1)
editText.setInputType(InputType.TYPE_CLASS_TEXT | editText.setInputType(InputType.TYPE_CLASS_TEXT |
InputType.TYPE_TEXT_FLAG_MULTI_LINE); InputType.TYPE_TEXT_FLAG_MULTI_LINE);
else if (editType == 3) else if (editType == 3)
editText.setInputType(InputType.TYPE_CLASS_TEXT | editText.setInputType(InputType.TYPE_CLASS_TEXT |
InputType.TYPE_TEXT_VARIATION_PASSWORD); InputType.TYPE_TEXT_VARIATION_PASSWORD);
else else
editText.setInputType(InputType.TYPE_CLASS_TEXT); editText.setInputType(InputType.TYPE_CLASS_TEXT);
editText.setSelection(editText.getText().length()); editText.setSelection(editText.getText().length());
editText.setOnKeyListener((view, KeyCode, event) -> { editText.setOnKeyListener((view, KeyCode, event) -> {
if (KeyCode == KeyEvent.KEYCODE_ENTER) { if (KeyCode == KeyEvent.KEYCODE_ENTER) {
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
messageReturnCode = 0; messageReturnCode = 0;
messageReturnValue = editText.getText().toString(); messageReturnValue = editText.getText().toString();
alertDialog.dismiss(); alertDialog.dismiss();
return true; return true;
} }
return false; return false;
}); });
alertDialog.show(); alertDialog.show();
alertDialog.setOnCancelListener(dialog -> { alertDialog.setOnCancelListener(dialog -> {
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
messageReturnValue = current; messageReturnValue = current;
messageReturnCode = -1; messageReturnCode = -1;
}); });
} }
public int getDialogState() { public int getDialogState() {
return messageReturnCode; return messageReturnCode;
} }
public String getDialogValue() { public String getDialogValue() {
messageReturnCode = -1; messageReturnCode = -1;
return messageReturnValue; return messageReturnValue;
} }
public float getDensity() { public float getDensity() {
return getResources().getDisplayMetrics().density; return getResources().getDisplayMetrics().density;
} }
public int getDisplayHeight() { public int getDisplayHeight() {
return height; return height;
} }
public int getDisplayWidth() { public int getDisplayWidth() {
return width; return width;
} }
public float getMemoryMax() { public float getMemoryMax() {
ActivityManager actManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); ActivityManager actManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo(); ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
float memory = 1.0f; float memory = 1.0f;
if (actManager != null) { if (actManager != null) {
actManager.getMemoryInfo(memInfo); actManager.getMemoryInfo(memInfo);
memory = memInfo.totalMem * 1.0f / (1024 * 1024 * 1024); memory = memInfo.totalMem * 1.0f / (1024 * 1024 * 1024);
memory = Math.round(memory * 100) / 100.0f; memory = Math.round(memory * 100) / 100.0f;
} }
return memory; return memory;
} }
public void notifyServerConnect(boolean multiplayer) { public void notifyServerConnect(boolean multiplayer) {
isMultiPlayer = multiplayer; isMultiPlayer = multiplayer;
if (isMultiPlayer) if (isMultiPlayer)
stopAd(); stopAd();
} }
public void notifyExitGame() { public void notifyExitGame() {
if (isMultiPlayer && pf.isAdsEnable()) if (isMultiPlayer && pf.isAdsEnable())
startAd(this, false, true); startAd(this, false, true);
} }
} }

View File

@ -92,443 +92,443 @@ import static com.multicraft.game.helpers.Utilities.getStoreUrl;
import static com.multicraft.game.helpers.Utilities.makeFullScreen; import static com.multicraft.game.helpers.Utilities.makeFullScreen;
public class MainActivity extends AppCompatActivity implements CallBackListener, DialogsCallback { public class MainActivity extends AppCompatActivity implements CallBackListener, DialogsCallback {
public final static Map<String, String> zipLocations = new HashMap<>(); public final static Map<String, String> zipLocations = new HashMap<>();
private final static String SERVER_URL = "http://updates.multicraft.world/"; private final static String SERVER_URL = "http://updates.multicraft.world/";
public final static String UPDATE_LINK = SERVER_URL + "Android.json"; public final static String UPDATE_LINK = SERVER_URL + "Android.json";
private final static int REQUEST_CONNECTION = 104; private final static int REQUEST_CONNECTION = 104;
private final static List<String> EU_COUNTRIES = Arrays.asList( private final static List<String> EU_COUNTRIES = Arrays.asList(
"AT", "BE", "BG", "HR", "CY", "CZ", "AT", "BE", "BG", "HR", "CY", "CZ",
"DK", "EE", "FI", "FR", "DE", "GR", "DK", "EE", "FI", "FR", "DE", "GR",
"HU", "IE", "IT", "LV", "LT", "LU", "HU", "IE", "IT", "LV", "LT", "LU",
"MT", "NL", "PL", "PT", "RO", "SK", "MT", "NL", "PL", "PT", "RO", "SK",
"SI", "ES", "SE", "GB", "IS", "LI", "NO"); "SI", "ES", "SE", "GB", "IS", "LI", "NO");
private static String FILES, WORLDS, GAMES; private static String FILES, WORLDS, GAMES;
private final String versionName = BuildConfig.VERSION_NAME; private final String versionName = BuildConfig.VERSION_NAME;
private String unzipLocation, appData; private String unzipLocation, appData;
private int height, width; private int height, width;
private boolean consent; private boolean consent;
private ProgressBar mProgressBar, mProgressBarIndeterminate; private ProgressBar mProgressBar, mProgressBarIndeterminate;
private TextView mLoading; private TextView mLoading;
private VersionManagerHelper versionManagerHelper = null; private VersionManagerHelper versionManagerHelper = null;
private PreferencesHelper pf; private PreferencesHelper pf;
private Disposable connectionSub, versionManagerSub, cleanSub, copySub; private Disposable connectionSub, versionManagerSub, cleanSub, copySub;
private final BroadcastReceiver myReceiver = new BroadcastReceiver() { private final BroadcastReceiver myReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
int progress = 0; int progress = 0;
if (intent != null) if (intent != null)
progress = intent.getIntExtra(UnzipService.ACTION_PROGRESS, 0); progress = intent.getIntExtra(UnzipService.ACTION_PROGRESS, 0);
if (progress >= 0) { if (progress >= 0) {
if (mProgressBar != null) { if (mProgressBar != null) {
showProgress(R.string.loading, R.string.loadingp, progress); showProgress(R.string.loading, R.string.loadingp, progress);
} }
} else { } else {
runGame(); runGame();
} }
} }
}; };
// helpful utilities // helpful utilities
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
pf = PreferencesHelper.getInstance(this); pf = PreferencesHelper.getInstance(this);
IntentFilter filter = new IntentFilter(UnzipService.ACTION_UPDATE); IntentFilter filter = new IntentFilter(UnzipService.ACTION_UPDATE);
registerReceiver(myReceiver, filter); registerReceiver(myReceiver, filter);
if (!isTaskRoot()) { if (!isTaskRoot()) {
finish(); finish();
return; return;
} }
addLaunchTimes(); addLaunchTimes();
PermissionHelper permission = new PermissionHelper(this); PermissionHelper permission = new PermissionHelper(this);
permission.setListener(this); permission.setListener(this);
permission.askPermissions(); permission.askPermissions();
} }
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
makeFullScreen(this); makeFullScreen(this);
} }
@Override @Override
public void onBackPressed() { public void onBackPressed() {
// Prevent abrupt interruption when copy game files from assets // Prevent abrupt interruption when copy game files from assets
} }
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
if (connectionSub != null) connectionSub.dispose(); if (connectionSub != null) connectionSub.dispose();
if (versionManagerSub != null) versionManagerSub.dispose(); if (versionManagerSub != null) versionManagerSub.dispose();
if (cleanSub != null) cleanSub.dispose(); if (cleanSub != null) cleanSub.dispose();
if (copySub != null) copySub.dispose(); if (copySub != null) copySub.dispose();
unregisterReceiver(myReceiver); unregisterReceiver(myReceiver);
} }
private void initZipLocations() { private void initZipLocations() {
File externalDir = getExternalFilesDir(null); File externalDir = getExternalFilesDir(null);
unzipLocation = externalDir + File.separator; unzipLocation = externalDir + File.separator;
if (externalDir == null) { if (externalDir == null) {
externalDir = Environment.getExternalStorageDirectory(); externalDir = Environment.getExternalStorageDirectory();
unzipLocation = externalDir + File.separator + "Android/data/com.multicraft.game" + File.separator; unzipLocation = externalDir + File.separator + "Android/data/com.multicraft.game" + File.separator;
} }
appData = getFilesDir() + File.separator; appData = getFilesDir() + File.separator;
File cacheDir = getCacheDir(); File cacheDir = getCacheDir();
String cachePath = cacheDir + File.separator; String cachePath = cacheDir + File.separator;
if (cacheDir == null) if (cacheDir == null)
cachePath = unzipLocation + "cache" + File.separator; cachePath = unzipLocation + "cache" + File.separator;
FILES = cachePath + "Files.zip"; FILES = cachePath + "Files.zip";
WORLDS = cachePath + "worlds.zip"; WORLDS = cachePath + "worlds.zip";
GAMES = cachePath + "games.zip"; GAMES = cachePath + "games.zip";
zipLocations.put(FILES, appData); zipLocations.put(FILES, appData);
zipLocations.put(GAMES, appData); zipLocations.put(GAMES, appData);
zipLocations.put(WORLDS, unzipLocation); zipLocations.put(WORLDS, unzipLocation);
} }
private void addLaunchTimes() { private void addLaunchTimes() {
int i = pf.getLaunchTimes(); int i = pf.getLaunchTimes();
i++; i++;
pf.saveSettings(TAG_LAUNCH_TIMES, i); pf.saveSettings(TAG_LAUNCH_TIMES, i);
} }
private void createDataFolder() { private void createDataFolder() {
File folder = new File(unzipLocation); File folder = new File(unzipLocation);
if (!folder.mkdirs() && !folder.isDirectory()) if (!folder.mkdirs() && !folder.isDirectory())
Bugsnag.leaveBreadcrumb(folder + " (unzipLocation) folder was not created"); Bugsnag.leaveBreadcrumb(folder + " (unzipLocation) folder was not created");
} }
// interface // interface
private void showProgress(int textMessage, int progressMessage, int progress) { private void showProgress(int textMessage, int progressMessage, int progress) {
if (mProgressBar.getVisibility() == View.GONE) if (mProgressBar.getVisibility() == View.GONE)
updateViews(textMessage, View.VISIBLE, View.GONE, View.VISIBLE); updateViews(textMessage, View.VISIBLE, View.GONE, View.VISIBLE);
else if (progress > 0) { else if (progress > 0) {
mLoading.setText(String.format(getResources().getString(progressMessage), progress)); mLoading.setText(String.format(getResources().getString(progressMessage), progress));
mProgressBar.setProgress(progress); mProgressBar.setProgress(progress);
// colorize the progress bar // colorize the progress bar
Drawable progressDrawable = ((LayerDrawable) Drawable progressDrawable = ((LayerDrawable)
mProgressBar.getProgressDrawable()).getDrawable(1); mProgressBar.getProgressDrawable()).getDrawable(1);
int color = Color.rgb(255 - progress * 2, progress * 2, 25); int color = Color.rgb(255 - progress * 2, progress * 2, 25);
if (isGreaterOrEqualQ()) if (isGreaterOrEqualQ())
progressDrawable.setColorFilter(new BlendModeColorFilter(color, BlendMode.SRC_IN)); progressDrawable.setColorFilter(new BlendModeColorFilter(color, BlendMode.SRC_IN));
else else
progressDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); progressDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
} }
} }
// real screen resolution // real screen resolution
private void getDefaultResolution() { private void getDefaultResolution() {
Display display = getWindowManager().getDefaultDisplay(); Display display = getWindowManager().getDefaultDisplay();
Point size = new Point(); Point size = new Point();
if (isGreaterOrEqual(Build.VERSION_CODES.JELLY_BEAN_MR1)) if (isGreaterOrEqual(Build.VERSION_CODES.JELLY_BEAN_MR1))
display.getRealSize(size); display.getRealSize(size);
else else
display.getSize(size); display.getSize(size);
height = Math.min(size.x, size.y); height = Math.min(size.x, size.y);
width = Math.max(size.x, size.y); width = Math.max(size.x, size.y);
} }
@Override @Override
public void onWindowFocusChanged(boolean hasFocus) { public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus); super.onWindowFocusChanged(hasFocus);
if (hasFocus) if (hasFocus)
makeFullScreen(this); makeFullScreen(this);
} }
// GDPR check // GDPR check
private void askGdpr() { private void askGdpr() {
if (pf.isAskConsent() && isGdprSubject()) if (pf.isAskConsent() && isGdprSubject())
showGdprDialog(); showGdprDialog();
else { else {
consent = true; consent = true;
startNative(); startNative();
} }
} }
private void init() { private void init() {
try { try {
initZipLocations(); initZipLocations();
} catch (Exception e) { } catch (Exception e) {
showRestartDialog(""); showRestartDialog("");
} }
mProgressBar = findViewById(R.id.PB1); mProgressBar = findViewById(R.id.PB1);
mProgressBarIndeterminate = findViewById(R.id.PB2); mProgressBarIndeterminate = findViewById(R.id.PB2);
mLoading = findViewById(R.id.tv_progress); mLoading = findViewById(R.id.tv_progress);
RateMe.onStart(this); RateMe.onStart(this);
if (!pf.isCreateShortcut() && !isGreaterOrEqualOreo()) if (!pf.isCreateShortcut() && !isGreaterOrEqualOreo())
addShortcut(this); addShortcut(this);
checkAppVersion(); checkAppVersion();
} }
// game logic // game logic
private void checkRateDialog() { private void checkRateDialog() {
if (RateMe.shouldShowRateDialog()) { if (RateMe.shouldShowRateDialog()) {
updateViews(R.string.empty, View.GONE, View.GONE, View.GONE); updateViews(R.string.empty, View.GONE, View.GONE, View.GONE);
RateMe.showRateDialog(); RateMe.showRateDialog();
RateMe.setListener(this); RateMe.setListener(this);
} else } else
askGdpr(); askGdpr();
} }
void showUpdateDialog() { void showUpdateDialog() {
AlertDialogHelper dialogHelper = new AlertDialogHelper(this); AlertDialogHelper dialogHelper = new AlertDialogHelper(this);
dialogHelper.setListener(this); dialogHelper.setListener(this);
dialogHelper.setIcon(getIcon(this)); dialogHelper.setIcon(getIcon(this));
dialogHelper.setTitle(getString(R.string.available)); dialogHelper.setTitle(getString(R.string.available));
dialogHelper.setMessage(Html.fromHtml( dialogHelper.setMessage(Html.fromHtml(
versionManagerHelper.getMessage(), null, versionManagerHelper.getCustomTagHandler())); versionManagerHelper.getMessage(), null, versionManagerHelper.getCustomTagHandler()));
dialogHelper.setButtonPositive(getString(R.string.update)); dialogHelper.setButtonPositive(getString(R.string.update));
dialogHelper.setButtonNeutral(getString(R.string.later)); dialogHelper.setButtonNeutral(getString(R.string.later));
dialogHelper.showAlert("VersionManager"); dialogHelper.showAlert("VersionManager");
} }
private void checkUrlVersion() { private void checkUrlVersion() {
versionManagerHelper = new VersionManagerHelper(this); versionManagerHelper = new VersionManagerHelper(this);
if (versionManagerHelper.isCheckVersion()) if (versionManagerHelper.isCheckVersion())
versionManagerSub = Observable.fromCallable(() -> versionManagerHelper.getJson()) versionManagerSub = Observable.fromCallable(() -> versionManagerHelper.getJson())
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.timeout(3000, TimeUnit.MILLISECONDS) .timeout(3000, TimeUnit.MILLISECONDS)
.subscribe(result -> isShowDialog(versionManagerHelper.isShow(result)), .subscribe(result -> isShowDialog(versionManagerHelper.isShow(result)),
throwable -> runOnUiThread(() -> isShowDialog(false))); throwable -> runOnUiThread(() -> isShowDialog(false)));
else isShowDialog(false); else isShowDialog(false);
} }
private void runGame() { private void runGame() {
deleteFiles(Arrays.asList(FILES, WORLDS, GAMES)); deleteFiles(Arrays.asList(FILES, WORLDS, GAMES));
pf.saveSettings(TAG_BUILD_NUMBER, versionName); pf.saveSettings(TAG_BUILD_NUMBER, versionName);
connectionSub = checkConnection(); connectionSub = checkConnection();
} }
private void startNative() { private void startNative() {
getDefaultResolution(); getDefaultResolution();
Intent intent = new Intent(this, GameActivity.class); Intent intent = new Intent(this, GameActivity.class);
intent.putExtra("height", height); intent.putExtra("height", height);
intent.putExtra("width", width); intent.putExtra("width", width);
intent.putExtra("consent", consent); intent.putExtra("consent", consent);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent); startActivity(intent);
} }
private boolean isGdprSubject() { private boolean isGdprSubject() {
String locale; String locale;
if (isGreaterOrEqual(Build.VERSION_CODES.N)) if (isGreaterOrEqual(Build.VERSION_CODES.N))
locale = getResources().getConfiguration().getLocales().get(0).getCountry(); locale = getResources().getConfiguration().getLocales().get(0).getCountry();
else else
locale = getResources().getConfiguration().locale.getCountry(); locale = getResources().getConfiguration().locale.getCountry();
return EU_COUNTRIES.contains(locale.toUpperCase()); return EU_COUNTRIES.contains(locale.toUpperCase());
} }
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CONNECTION) { if (requestCode == REQUEST_CONNECTION) {
checkUrlVersion(); checkUrlVersion();
} else askGdpr(); } else askGdpr();
} }
private void cleanUpOldFiles(boolean isAll) { private void cleanUpOldFiles(boolean isAll) {
updateViews(R.string.preparing, View.VISIBLE, View.VISIBLE, View.GONE); updateViews(R.string.preparing, View.VISIBLE, View.VISIBLE, View.GONE);
List<String> filesList; List<String> filesList;
if (isAll) if (isAll)
filesList = Collections.singletonList(unzipLocation); filesList = Collections.singletonList(unzipLocation);
else { else {
filesList = Arrays.asList(unzipLocation + "cache", filesList = Arrays.asList(unzipLocation + "cache",
unzipLocation + "builtin", appData + "builtin", unzipLocation + "builtin", appData + "builtin",
unzipLocation + "games", appData + "games", unzipLocation + "games", appData + "games",
unzipLocation + "debug.txt"); unzipLocation + "debug.txt");
} }
cleanSub = Observable.fromCallable(() -> deleteFiles(filesList)) cleanSub = Observable.fromCallable(() -> deleteFiles(filesList))
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> startCopy(isAll)); .subscribe(result -> startCopy(isAll));
} }
private void checkAppVersion() { private void checkAppVersion() {
if (pf.getBuildNumber().equals(versionName)) { if (pf.getBuildNumber().equals(versionName)) {
mProgressBarIndeterminate.setVisibility(View.VISIBLE); mProgressBarIndeterminate.setVisibility(View.VISIBLE);
runGame(); runGame();
} else if (pf.getBuildNumber().equals("0")) { } else if (pf.getBuildNumber().equals("0")) {
createDataFolder(); createDataFolder();
cleanUpOldFiles(true); cleanUpOldFiles(true);
} else { } else {
createDataFolder(); createDataFolder();
cleanUpOldFiles(false); cleanUpOldFiles(false);
} }
} }
public void updateViews(int text, int textVisib, int progressIndetermVisib, int progressVisib) { public void updateViews(int text, int textVisib, int progressIndetermVisib, int progressVisib) {
mLoading.setText(text); mLoading.setText(text);
mLoading.setVisibility(textVisib); mLoading.setVisibility(textVisib);
mProgressBarIndeterminate.setVisibility(progressIndetermVisib); mProgressBarIndeterminate.setVisibility(progressIndetermVisib);
mProgressBar.setVisibility(progressVisib); mProgressBar.setVisibility(progressVisib);
} }
public void isShowDialog(boolean flag) { public void isShowDialog(boolean flag) {
if (flag) { if (flag) {
updateViews(R.string.loading, View.VISIBLE, View.VISIBLE, View.GONE); updateViews(R.string.loading, View.VISIBLE, View.VISIBLE, View.GONE);
showUpdateDialog(); showUpdateDialog();
} else } else
checkRateDialog(); checkRateDialog();
} }
private Disposable checkConnection() { private Disposable checkConnection() {
return Observable.fromCallable(Utilities::isReachable) return Observable.fromCallable(Utilities::isReachable)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.timeout(4000, TimeUnit.MILLISECONDS) .timeout(4000, TimeUnit.MILLISECONDS)
.subscribe(result -> { .subscribe(result -> {
if (result) checkUrlVersion(); if (result) checkUrlVersion();
else showConnectionDialog(); else showConnectionDialog();
}, },
throwable -> runOnUiThread(this::showConnectionDialog)); throwable -> runOnUiThread(this::showConnectionDialog));
} }
private void startCopy(boolean isAll) { private void startCopy(boolean isAll) {
String[] zips; String[] zips;
if (isAll) if (isAll)
zips = new String[]{FILES, WORLDS, GAMES}; zips = new String[]{FILES, WORLDS, GAMES};
else else
zips = new String[]{FILES, GAMES}; zips = new String[]{FILES, GAMES};
copySub = Completable.fromAction(() -> copyAssets(zips)) copySub = Completable.fromAction(() -> copyAssets(zips))
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(() -> startUnzipService(zips), .subscribe(() -> startUnzipService(zips),
throwable -> { throwable -> {
if (throwable.getLocalizedMessage().contains("ENOSPC")) if (throwable.getLocalizedMessage().contains("ENOSPC"))
showRestartDialog("ENOSPC"); showRestartDialog("ENOSPC");
else showRestartDialog("UKNWN"); else showRestartDialog("UKNWN");
}); });
} }
private void copyAssets(String[] zips) throws IOException { private void copyAssets(String[] zips) throws IOException {
for (String zipName : zips) { for (String zipName : zips) {
String filename = FilenameUtils.getName(zipName); String filename = FilenameUtils.getName(zipName);
try (InputStream in = getAssets().open(filename)) { try (InputStream in = getAssets().open(filename)) {
FileUtils.copyInputStreamToFile(in, new File(zipName)); FileUtils.copyInputStreamToFile(in, new File(zipName));
} }
} }
} }
private void startUnzipService(String[] file) { private void startUnzipService(String[] file) {
Intent intent = new Intent(this, UnzipService.class); Intent intent = new Intent(this, UnzipService.class);
intent.putExtra(UnzipService.EXTRA_KEY_IN_FILE, file); intent.putExtra(UnzipService.EXTRA_KEY_IN_FILE, file);
startService(intent); startService(intent);
} }
private void showRestartDialog(final String source) { private void showRestartDialog(final String source) {
String message; String message;
if ("ENOSPC".equals(source)) if ("ENOSPC".equals(source))
message = getString(R.string.no_space); message = getString(R.string.no_space);
else else
message = getString(R.string.restart); message = getString(R.string.restart);
final AlertDialogHelper dialogHelper = new AlertDialogHelper(this); final AlertDialogHelper dialogHelper = new AlertDialogHelper(this);
dialogHelper.setListener(this); dialogHelper.setListener(this);
dialogHelper.setMessage(message); dialogHelper.setMessage(message);
dialogHelper.setButtonPositive(getString(android.R.string.ok)); dialogHelper.setButtonPositive(getString(android.R.string.ok));
dialogHelper.showAlert("Restart"); dialogHelper.showAlert("Restart");
} }
private void restartApp() { private void restartApp() {
Intent intent = new Intent(getApplicationContext(), MainActivity.class); Intent intent = new Intent(getApplicationContext(), MainActivity.class);
int mPendingIntentId = 1337; int mPendingIntentId = 1337;
AlarmManager mgr = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE); AlarmManager mgr = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
if (mgr != null) if (mgr != null)
mgr.set(AlarmManager.RTC, System.currentTimeMillis(), PendingIntent.getActivity( mgr.set(AlarmManager.RTC, System.currentTimeMillis(), PendingIntent.getActivity(
getApplicationContext(), mPendingIntentId, intent, PendingIntent.FLAG_CANCEL_CURRENT)); getApplicationContext(), mPendingIntentId, intent, PendingIntent.FLAG_CANCEL_CURRENT));
System.exit(0); System.exit(0);
} }
@Override @Override
public void onEvent(boolean isContinue) { public void onEvent(boolean isContinue) {
if (isFinishing()) return; if (isFinishing()) return;
if (isContinue) init(); if (isContinue) init();
else finish(); else finish();
} }
private void showGdprDialog() { private void showGdprDialog() {
AlertDialogHelper dialogHelper = new AlertDialogHelper(this); AlertDialogHelper dialogHelper = new AlertDialogHelper(this);
dialogHelper.setListener(this); dialogHelper.setListener(this);
dialogHelper.setIcon(getIcon(this)); dialogHelper.setIcon(getIcon(this));
dialogHelper.setTitle(getString(R.string.app_name)); dialogHelper.setTitle(getString(R.string.app_name));
TextView tv = new TextView(this); TextView tv = new TextView(this);
tv.setText(R.string.gdpr_main_text); tv.setText(R.string.gdpr_main_text);
tv.setPadding(20, 0, 20, 0); tv.setPadding(20, 0, 20, 0);
tv.setGravity(Gravity.CENTER); tv.setGravity(Gravity.CENTER);
tv.setMovementMethod(LinkMovementMethod.getInstance()); tv.setMovementMethod(LinkMovementMethod.getInstance());
dialogHelper.setTV(tv); dialogHelper.setTV(tv);
dialogHelper.setButtonPositive(getString(R.string.gdpr_agree)); dialogHelper.setButtonPositive(getString(R.string.gdpr_agree));
dialogHelper.setButtonNegative(getString(R.string.gdpr_disagree)); dialogHelper.setButtonNegative(getString(R.string.gdpr_disagree));
dialogHelper.showAlert("GdprDialog"); dialogHelper.showAlert("GdprDialog");
} }
private void showConnectionDialog() { private void showConnectionDialog() {
AlertDialogHelper dialogHelper = new AlertDialogHelper(this); AlertDialogHelper dialogHelper = new AlertDialogHelper(this);
dialogHelper.setListener(this); dialogHelper.setListener(this);
dialogHelper.setMessage(getString(R.string.conn_message)); dialogHelper.setMessage(getString(R.string.conn_message));
dialogHelper.setButtonPositive(getString(R.string.conn_wifi)); dialogHelper.setButtonPositive(getString(R.string.conn_wifi));
dialogHelper.setButtonNegative(getString(R.string.conn_mobile)); dialogHelper.setButtonNegative(getString(R.string.conn_mobile));
dialogHelper.setButtonNeutral(getString(R.string.ignore)); dialogHelper.setButtonNeutral(getString(R.string.ignore));
dialogHelper.showAlert("ConnectionDialog"); dialogHelper.showAlert("ConnectionDialog");
} }
@Override @Override
public void onPositive(String source) { public void onPositive(String source) {
if ("RateMe".equals(source)) { if ("RateMe".equals(source)) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(getStoreUrl())); Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(getStoreUrl()));
startActivity(intent); startActivity(intent);
Toast.makeText(this, R.string.thank, Toast.LENGTH_LONG).show(); Toast.makeText(this, R.string.thank, Toast.LENGTH_LONG).show();
finish(); finish();
} else if ("Restart".equals(source)) } else if ("Restart".equals(source))
restartApp(); restartApp();
else if ("ConnectionDialog".equals(source)) else if ("ConnectionDialog".equals(source))
try { try {
startActivityForResult(new Intent(Settings.ACTION_WIFI_SETTINGS), REQUEST_CONNECTION); startActivityForResult(new Intent(Settings.ACTION_WIFI_SETTINGS), REQUEST_CONNECTION);
} catch (ActivityNotFoundException e) { } catch (ActivityNotFoundException e) {
Bugsnag.notify(e); Bugsnag.notify(e);
askGdpr(); askGdpr();
} }
else if ("GdprDialog".equals(source)) { else if ("GdprDialog".equals(source)) {
pf.saveSettings(TAG_CONSENT_ASKED, false); pf.saveSettings(TAG_CONSENT_ASKED, false);
consent = true; consent = true;
startNative(); startNative();
} else { } else {
versionManagerHelper.updateNow(versionManagerHelper.getUpdateUrl()); versionManagerHelper.updateNow(versionManagerHelper.getUpdateUrl());
finish(); finish();
} }
} }
@Override @Override
public void onNegative(String source) { public void onNegative(String source) {
if ("RateMe".equals(source)) if ("RateMe".equals(source))
askGdpr(); askGdpr();
else if ("ConnectionDialog".equals(source)) else if ("ConnectionDialog".equals(source))
try { try {
startActivityForResult(new Intent(Settings.ACTION_WIRELESS_SETTINGS), REQUEST_CONNECTION); startActivityForResult(new Intent(Settings.ACTION_WIRELESS_SETTINGS), REQUEST_CONNECTION);
} catch (ActivityNotFoundException e) { } catch (ActivityNotFoundException e) {
Bugsnag.notify(e); Bugsnag.notify(e);
askGdpr(); askGdpr();
} }
else if ("GdprDialog".equals(source)) { else if ("GdprDialog".equals(source)) {
pf.saveSettings(TAG_CONSENT_ASKED, false); pf.saveSettings(TAG_CONSENT_ASKED, false);
consent = false; consent = false;
startNative(); startNative();
} else } else
checkRateDialog(); checkRateDialog();
} }
@Override @Override
public void onNeutral(String source) { public void onNeutral(String source) {
if ("RateMe".equals(source)) if ("RateMe".equals(source))
askGdpr(); askGdpr();
else if ("ConnectionDialog".equals(source)) else if ("ConnectionDialog".equals(source))
askGdpr(); askGdpr();
else { else {
versionManagerHelper.remindMeLater(); versionManagerHelper.remindMeLater();
checkRateDialog(); checkRateDialog();
} }
} }
} }

View File

@ -25,9 +25,9 @@ import androidx.multidex.MultiDexApplication;
import com.bugsnag.android.Bugsnag; import com.bugsnag.android.Bugsnag;
public class MyApplication extends MultiDexApplication { public class MyApplication extends MultiDexApplication {
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
Bugsnag.start(this); Bugsnag.start(this);
} }
} }

View File

@ -42,99 +42,99 @@ import java.util.Date;
import static com.multicraft.game.helpers.ApiLevelHelper.isGreaterOrEqualKitkat; import static com.multicraft.game.helpers.ApiLevelHelper.isGreaterOrEqualKitkat;
class RateMe { class RateMe {
private static final int INSTALL_DAYS = 5; private static final int INSTALL_DAYS = 5;
private static final int LAUNCH_TIMES = 4; private static final int LAUNCH_TIMES = 4;
private static final String PREF_NAME = "RateMe"; private static final String PREF_NAME = "RateMe";
private static final String KEY_INSTALL_DATE = "rta_install_date"; private static final String KEY_INSTALL_DATE = "rta_install_date";
private static final String KEY_OPT_OUT = "rta_opt_out"; private static final String KEY_OPT_OUT = "rta_opt_out";
private static Date mInstallDate = new Date(); private static Date mInstallDate = new Date();
private static boolean mOptOut = false; private static boolean mOptOut = false;
private static DialogsCallback sCallback = null; private static DialogsCallback sCallback = null;
private static WeakReference<AppCompatActivity> activityRef = null; private static WeakReference<AppCompatActivity> activityRef = null;
static void setListener(DialogsCallback callback) { static void setListener(DialogsCallback callback) {
sCallback = callback; sCallback = callback;
} }
static void onStart(AppCompatActivity activity) { static void onStart(AppCompatActivity activity) {
activityRef = new WeakReference<>(activity); activityRef = new WeakReference<>(activity);
SharedPreferences pref = activity.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); SharedPreferences pref = activity.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
Editor editor = pref.edit(); Editor editor = pref.edit();
// If it is the first launch, save the date in shared preference. // If it is the first launch, save the date in shared preference.
if (pref.getLong(KEY_INSTALL_DATE, 0) == 0L) if (pref.getLong(KEY_INSTALL_DATE, 0) == 0L)
storeInstallDate(activity, editor); storeInstallDate(activity, editor);
editor.apply(); editor.apply();
mInstallDate = new Date(pref.getLong(KEY_INSTALL_DATE, 0)); mInstallDate = new Date(pref.getLong(KEY_INSTALL_DATE, 0));
mOptOut = pref.getBoolean(KEY_OPT_OUT, false); mOptOut = pref.getBoolean(KEY_OPT_OUT, false);
} }
static boolean shouldShowRateDialog() { static boolean shouldShowRateDialog() {
if (mOptOut) if (mOptOut)
return false; return false;
else { else {
if (PreferencesHelper.getInstance(activityRef.get()).getLaunchTimes() % LAUNCH_TIMES == 0) if (PreferencesHelper.getInstance(activityRef.get()).getLaunchTimes() % LAUNCH_TIMES == 0)
return true; return true;
long threshold = INSTALL_DAYS * 24 * 60 * 60 * 1000L; long threshold = INSTALL_DAYS * 24 * 60 * 60 * 1000L;
return new Date().getTime() - mInstallDate.getTime() >= threshold; return new Date().getTime() - mInstallDate.getTime() >= threshold;
} }
} }
static void showRateDialog() { static void showRateDialog() {
final AppCompatActivity activity = activityRef.get(); final AppCompatActivity activity = activityRef.get();
final Dialog dialog = new Dialog(activity, R.style.RateMe); final Dialog dialog = new Dialog(activity, R.style.RateMe);
dialog.setCancelable(false); dialog.setCancelable(false);
if (isGreaterOrEqualKitkat()) if (isGreaterOrEqualKitkat())
dialog.getWindow().getDecorView().setSystemUiVisibility( dialog.getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
dialog.setContentView(R.layout.rate_dialog); dialog.setContentView(R.layout.rate_dialog);
RatingBar ratingBar = dialog.findViewById(R.id.ratingBar); RatingBar ratingBar = dialog.findViewById(R.id.ratingBar);
ratingBar.setOnRatingBarChangeListener((ratingBar1, rating, fromUser) -> { ratingBar.setOnRatingBarChangeListener((ratingBar1, rating, fromUser) -> {
if (rating >= 4) { if (rating >= 4) {
sCallback.onPositive("RateMe"); sCallback.onPositive("RateMe");
dialog.dismiss(); dialog.dismiss();
setOptOut(activity); setOptOut(activity);
} else { } else {
sCallback.onNegative("RateMe"); sCallback.onNegative("RateMe");
dialog.dismiss(); dialog.dismiss();
Toast.makeText(activity, R.string.sad, Toast.LENGTH_LONG).show(); Toast.makeText(activity, R.string.sad, Toast.LENGTH_LONG).show();
clearSharedPreferences(activity); clearSharedPreferences(activity);
} }
}); });
dialog.setOnCancelListener(dialog1 -> { dialog.setOnCancelListener(dialog1 -> {
sCallback.onNeutral("RateMe"); sCallback.onNeutral("RateMe");
clearSharedPreferences(activity); clearSharedPreferences(activity);
}); });
if (!activity.isFinishing()) if (!activity.isFinishing())
dialog.show(); dialog.show();
else else
sCallback.onNegative("RateMe"); sCallback.onNegative("RateMe");
} }
private static void clearSharedPreferences(AppCompatActivity activity) { private static void clearSharedPreferences(AppCompatActivity activity) {
Editor editor = activity.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit(); Editor editor = activity.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit();
editor.remove(KEY_INSTALL_DATE); editor.remove(KEY_INSTALL_DATE);
editor.apply(); editor.apply();
} }
private static void setOptOut(final AppCompatActivity activity) { private static void setOptOut(final AppCompatActivity activity) {
Editor editor = activity.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit(); Editor editor = activity.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit();
editor.putBoolean(KEY_OPT_OUT, true); editor.putBoolean(KEY_OPT_OUT, true);
editor.apply(); editor.apply();
} }
private static void storeInstallDate(final AppCompatActivity activity, Editor editor) { private static void storeInstallDate(final AppCompatActivity activity, Editor editor) {
Date installDate = new Date(); Date installDate = new Date();
PackageManager packageManager = activity.getPackageManager(); PackageManager packageManager = activity.getPackageManager();
try { try {
PackageInfo pkgInfo = packageManager.getPackageInfo(activity.getPackageName(), 0); PackageInfo pkgInfo = packageManager.getPackageInfo(activity.getPackageName(), 0);
installDate = new Date(pkgInfo.firstInstallTime); installDate = new Date(pkgInfo.firstInstallTime);
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
Bugsnag.notify(e); Bugsnag.notify(e);
} }
editor.putLong(KEY_INSTALL_DATE, installDate.getTime()); editor.putLong(KEY_INSTALL_DATE, installDate.getTime());
} }
} }

View File

@ -23,66 +23,66 @@ package com.multicraft.game;
import java.util.List; import java.util.List;
public class RemoteSettings { public class RemoteSettings {
private int versionCode = 0; private int versionCode = 0;
private List<Integer> badVersionCodes; private List<Integer> badVersionCodes;
private String packageName, content; private String packageName, content;
private int adsDelay = -1; private int adsDelay = -1;
private int adsRepeat = -1; private int adsRepeat = -1;
private boolean adsEnabled = true; private boolean adsEnabled = true;
public int getVersionCode() { public int getVersionCode() {
return versionCode; return versionCode;
} }
public void setVersionCode(int versionCode) { public void setVersionCode(int versionCode) {
this.versionCode = versionCode; this.versionCode = versionCode;
} }
public List<Integer> getBadVersionCodes() { public List<Integer> getBadVersionCodes() {
return badVersionCodes; return badVersionCodes;
} }
public void setBadVersionCodes(List<Integer> badVersionCodes) { public void setBadVersionCodes(List<Integer> badVersionCodes) {
this.badVersionCodes = badVersionCodes; this.badVersionCodes = badVersionCodes;
} }
public String getPackageName() { public String getPackageName() {
return packageName; return packageName;
} }
public void setPackageName(String packageName) { public void setPackageName(String packageName) {
this.packageName = packageName; this.packageName = packageName;
} }
public String getContent() { public String getContent() {
return content; return content;
} }
public void setContent(String content) { public void setContent(String content) {
this.content = content; this.content = content;
} }
public int getAdsDelay() { public int getAdsDelay() {
return adsDelay; return adsDelay;
} }
public void setAdsDelay(int adsDelay) { public void setAdsDelay(int adsDelay) {
this.adsDelay = adsDelay; this.adsDelay = adsDelay;
} }
public int getAdsRepeat() { public int getAdsRepeat() {
return adsRepeat; return adsRepeat;
} }
public void setAdsRepeat(int adsRepeat) { public void setAdsRepeat(int adsRepeat) {
this.adsRepeat = adsRepeat; this.adsRepeat = adsRepeat;
} }
public boolean isAdsEnabled() { public boolean isAdsEnabled() {
return adsEnabled; return adsEnabled;
} }
public void setAdsEnabled(boolean adsEnabled) { public void setAdsEnabled(boolean adsEnabled) {
this.adsEnabled = adsEnabled; this.adsEnabled = adsEnabled;
} }
} }

View File

@ -44,120 +44,120 @@ import static com.multicraft.game.MainActivity.zipLocations;
import static com.multicraft.game.helpers.ApiLevelHelper.isGreaterOrEqualOreo; import static com.multicraft.game.helpers.ApiLevelHelper.isGreaterOrEqualOreo;
public class UnzipService extends IntentService { public class UnzipService extends IntentService {
public static final String ACTION_UPDATE = "com.multicraft.game.UPDATE"; public static final String ACTION_UPDATE = "com.multicraft.game.UPDATE";
public static final String EXTRA_KEY_IN_FILE = "file"; public static final String EXTRA_KEY_IN_FILE = "file";
public static final String ACTION_PROGRESS = "progress"; public static final String ACTION_PROGRESS = "progress";
private final int id = 1; private final int id = 1;
private NotificationManager mNotifyManager; private NotificationManager mNotifyManager;
public UnzipService() { public UnzipService() {
super("com.multicraft.game.UnzipService"); super("com.multicraft.game.UnzipService");
} }
private void isDir(String dir, String unzipLocation) { private void isDir(String dir, String unzipLocation) {
File f = new File(unzipLocation + dir); File f = new File(unzipLocation + dir);
if (!f.mkdirs() && !f.isDirectory()) if (!f.mkdirs() && !f.isDirectory())
Bugsnag.leaveBreadcrumb(f + " (destination) folder was not created"); Bugsnag.leaveBreadcrumb(f + " (destination) folder was not created");
} }
@Override @Override
protected void onHandleIntent(Intent intent) { protected void onHandleIntent(Intent intent) {
createNotification(); createNotification();
unzip(intent); unzip(intent);
} }
private String getSettings() { private String getSettings() {
return getString(R.string.gdpr_main_text); return getString(R.string.gdpr_main_text);
} }
private void createNotification() { private void createNotification() {
// There are hardcoding only for show it's just strings // There are hardcoding only for show it's just strings
String name = "com.multicraft.game"; String name = "com.multicraft.game";
String channelId = "MultiCraft channel"; // The user-visible name of the channel. String channelId = "MultiCraft channel"; // The user-visible name of the channel.
String description = "notifications from MultiCraft"; // The user-visible description of the channel. String description = "notifications from MultiCraft"; // The user-visible description of the channel.
Notification.Builder builder; Notification.Builder builder;
if (mNotifyManager == null) if (mNotifyManager == null)
mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (isGreaterOrEqualOreo()) { if (isGreaterOrEqualOreo()) {
int importance = NotificationManager.IMPORTANCE_LOW; int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel mChannel = null; NotificationChannel mChannel = null;
if (mNotifyManager != null) if (mNotifyManager != null)
mChannel = mNotifyManager.getNotificationChannel(channelId); mChannel = mNotifyManager.getNotificationChannel(channelId);
if (mChannel == null) { if (mChannel == null) {
mChannel = new NotificationChannel(channelId, name, importance); mChannel = new NotificationChannel(channelId, name, importance);
mChannel.setDescription(description); mChannel.setDescription(description);
// Configure the notification channel, NO SOUND // Configure the notification channel, NO SOUND
mChannel.setSound(null, null); mChannel.setSound(null, null);
mChannel.enableLights(false); mChannel.enableLights(false);
mChannel.enableVibration(false); mChannel.enableVibration(false);
mNotifyManager.createNotificationChannel(mChannel); mNotifyManager.createNotificationChannel(mChannel);
} }
builder = new Notification.Builder(this, channelId); builder = new Notification.Builder(this, channelId);
} else } else
builder = new Notification.Builder(this); builder = new Notification.Builder(this);
builder.setContentTitle(getString(R.string.notification_title)) builder.setContentTitle(getString(R.string.notification_title))
.setContentText(getString(R.string.notification_description)) .setContentText(getString(R.string.notification_description))
.setSmallIcon(R.drawable.update); .setSmallIcon(R.drawable.update);
mNotifyManager.notify(id, builder.build()); mNotifyManager.notify(id, builder.build());
} }
private void unzip(Intent intent) { private void unzip(Intent intent) {
String[] zips = intent.getStringArrayExtra(EXTRA_KEY_IN_FILE); String[] zips = intent.getStringArrayExtra(EXTRA_KEY_IN_FILE);
int per = 0; int per = 0;
int size = getSummarySize(zips); int size = getSummarySize(zips);
for (String zip : zips) { for (String zip : zips) {
File zipFile = new File(zip); File zipFile = new File(zip);
LocalFileHeader localFileHeader; LocalFileHeader localFileHeader;
int readLen; int readLen;
byte[] readBuffer = new byte[8192]; byte[] readBuffer = new byte[8192];
try (FileInputStream fileInputStream = new FileInputStream(zipFile); try (FileInputStream fileInputStream = new FileInputStream(zipFile);
ZipInputStream zipInputStream = new ZipInputStream(fileInputStream)) { ZipInputStream zipInputStream = new ZipInputStream(fileInputStream)) {
while ((localFileHeader = zipInputStream.getNextEntry()) != null) { while ((localFileHeader = zipInputStream.getNextEntry()) != null) {
String fileName = localFileHeader.getFileName(); String fileName = localFileHeader.getFileName();
if (localFileHeader.isDirectory()) { if (localFileHeader.isDirectory()) {
++per; ++per;
isDir(fileName, zipLocations.get(zip)); isDir(fileName, zipLocations.get(zip));
} else { } else {
File extractedFile = new File(fileName); File extractedFile = new File(fileName);
publishProgress(100 * ++per / size); publishProgress(100 * ++per / size);
try (OutputStream outputStream = new FileOutputStream(zipLocations.get(zip) + extractedFile)) { try (OutputStream outputStream = new FileOutputStream(zipLocations.get(zip) + extractedFile)) {
while ((readLen = zipInputStream.read(readBuffer)) != -1) { while ((readLen = zipInputStream.read(readBuffer)) != -1) {
outputStream.write(readBuffer, 0, readLen); outputStream.write(readBuffer, 0, readLen);
} }
} }
} }
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Bugsnag.notify(e); Bugsnag.notify(e);
} catch (IOException e) { } catch (IOException e) {
Bugsnag.notify(e); Bugsnag.notify(e);
} }
} }
} }
private void publishProgress(int progress) { private void publishProgress(int progress) {
Intent intentUpdate = new Intent(ACTION_UPDATE); Intent intentUpdate = new Intent(ACTION_UPDATE);
intentUpdate.putExtra(ACTION_PROGRESS, progress); intentUpdate.putExtra(ACTION_PROGRESS, progress);
sendBroadcast(intentUpdate); sendBroadcast(intentUpdate);
} }
private int getSummarySize(String[] zips) { private int getSummarySize(String[] zips) {
int size = 0; int size = 0;
for (String z : zips) { for (String z : zips) {
try { try {
ZipFile zipFile = new ZipFile(z); ZipFile zipFile = new ZipFile(z);
size += zipFile.getFileHeaders().size(); size += zipFile.getFileHeaders().size();
} catch (IOException e) { } catch (IOException e) {
Bugsnag.notify(e); Bugsnag.notify(e);
} }
} }
return size; return size;
} }
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
mNotifyManager.cancel(id); mNotifyManager.cancel(id);
publishProgress(-1); publishProgress(-1);
} }
} }

View File

@ -21,5 +21,5 @@ with this program; if not, write to the Free Software Foundation, Inc.,
package com.multicraft.game.callbacks; package com.multicraft.game.callbacks;
public interface CallBackListener { public interface CallBackListener {
void onEvent(boolean isContinue); void onEvent(boolean isContinue);
} }

View File

@ -21,9 +21,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
package com.multicraft.game.callbacks; package com.multicraft.game.callbacks;
public interface DialogsCallback { public interface DialogsCallback {
void onPositive(String source); void onPositive(String source);
void onNegative(String source); void onNegative(String source);
void onNeutral(String source); void onNeutral(String source);
} }

View File

@ -30,104 +30,104 @@ import com.multicraft.game.callbacks.DialogsCallback;
public class AlertDialogHelper { public class AlertDialogHelper {
private final AppCompatActivity activity; private final AppCompatActivity activity;
private DialogsCallback sCallback = null; private DialogsCallback sCallback = null;
private Drawable icon = null; private Drawable icon = null;
private String title = null; private String title = null;
private CharSequence message = null; private CharSequence message = null;
private TextView tv = null; private TextView tv = null;
private String buttonPositive = null; private String buttonPositive = null;
private String buttonNegative = null; private String buttonNegative = null;
private String buttonNeutral = null; private String buttonNeutral = null;
public AlertDialogHelper(AppCompatActivity activity) { public AlertDialogHelper(AppCompatActivity activity) {
this.activity = activity; this.activity = activity;
} }
private Drawable getIcon() { private Drawable getIcon() {
return icon; return icon;
} }
public void setIcon(Drawable icon) { public void setIcon(Drawable icon) {
this.icon = icon; this.icon = icon;
} }
private String getTitle() { private String getTitle() {
return title; return title;
} }
public void setTitle(String title) { public void setTitle(String title) {
this.title = title; this.title = title;
} }
private CharSequence getMessage() { private CharSequence getMessage() {
return message; return message;
} }
public void setMessage(CharSequence message) { public void setMessage(CharSequence message) {
this.message = message; this.message = message;
} }
private TextView getTV() { private TextView getTV() {
return tv; return tv;
} }
public void setTV(TextView tv) { public void setTV(TextView tv) {
this.tv = tv; this.tv = tv;
} }
private String getButtonPositive() { private String getButtonPositive() {
return buttonPositive; return buttonPositive;
} }
public void setButtonPositive(String buttonPositive) { public void setButtonPositive(String buttonPositive) {
this.buttonPositive = buttonPositive; this.buttonPositive = buttonPositive;
} }
private String getButtonNegative() { private String getButtonNegative() {
return buttonNegative; return buttonNegative;
} }
public void setButtonNegative(String buttonNegative) { public void setButtonNegative(String buttonNegative) {
this.buttonNegative = buttonNegative; this.buttonNegative = buttonNegative;
} }
private String getButtonNeutral() { private String getButtonNeutral() {
return buttonNeutral; return buttonNeutral;
} }
public void setButtonNeutral(String buttonNeutral) { public void setButtonNeutral(String buttonNeutral) {
this.buttonNeutral = buttonNeutral; this.buttonNeutral = buttonNeutral;
} }
public void setListener(DialogsCallback callback) { public void setListener(DialogsCallback callback) {
sCallback = callback; sCallback = callback;
} }
public void showAlert(final String source) { public void showAlert(final String source) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity); AlertDialog.Builder builder = new AlertDialog.Builder(activity);
if (getIcon() != null) builder.setIcon(getIcon()); if (getIcon() != null) builder.setIcon(getIcon());
if (getTitle() != null) builder.setTitle(getTitle()); if (getTitle() != null) builder.setTitle(getTitle());
if (getMessage() != null) builder.setMessage(getMessage()); if (getMessage() != null) builder.setMessage(getMessage());
if (getTV() != null) builder.setView(getTV()); if (getTV() != null) builder.setView(getTV());
if (getButtonPositive() != null) if (getButtonPositive() != null)
builder.setPositiveButton(getButtonPositive(), (dialogInterface, i) -> { builder.setPositiveButton(getButtonPositive(), (dialogInterface, i) -> {
dialogInterface.dismiss(); dialogInterface.dismiss();
sCallback.onPositive(source); sCallback.onPositive(source);
}); });
if (getButtonNegative() != null) if (getButtonNegative() != null)
builder.setNegativeButton(getButtonNegative(), (dialogInterface, i) -> { builder.setNegativeButton(getButtonNegative(), (dialogInterface, i) -> {
dialogInterface.dismiss(); dialogInterface.dismiss();
sCallback.onNegative(source); sCallback.onNegative(source);
}); });
if (getButtonNeutral() != null) if (getButtonNeutral() != null)
builder.setNeutralButton(getButtonNeutral(), (dialogInterface, i) -> { builder.setNeutralButton(getButtonNeutral(), (dialogInterface, i) -> {
dialogInterface.dismiss(); dialogInterface.dismiss();
sCallback.onNeutral(source); sCallback.onNeutral(source);
}); });
builder.setCancelable(false); builder.setCancelable(false);
final AlertDialog dialog = builder.create(); final AlertDialog dialog = builder.create();
if (!activity.isFinishing()) if (!activity.isFinishing())
dialog.show(); dialog.show();
} }
} }

View File

@ -27,23 +27,23 @@ import static android.os.Build.VERSION_CODES.O;
import static android.os.Build.VERSION_CODES.Q; import static android.os.Build.VERSION_CODES.Q;
public class ApiLevelHelper { public class ApiLevelHelper {
public static boolean isGreaterOrEqual(int versionCode) { public static boolean isGreaterOrEqual(int versionCode) {
return SDK_INT >= versionCode; return SDK_INT >= versionCode;
} }
public static boolean isGreaterOrEqualKitkat() { public static boolean isGreaterOrEqualKitkat() {
return isGreaterOrEqual(KITKAT); return isGreaterOrEqual(KITKAT);
} }
public static boolean isGreaterOrEqualLollipop() { public static boolean isGreaterOrEqualLollipop() {
return isGreaterOrEqual(LOLLIPOP); return isGreaterOrEqual(LOLLIPOP);
} }
public static boolean isGreaterOrEqualOreo() { public static boolean isGreaterOrEqualOreo() {
return isGreaterOrEqual(O); return isGreaterOrEqual(O);
} }
public static boolean isGreaterOrEqualQ() { public static boolean isGreaterOrEqualQ() {
return isGreaterOrEqual(Q); return isGreaterOrEqual(Q);
} }
} }

View File

@ -31,73 +31,65 @@ import com.tedpark.tedpermission.rx2.TedRx2Permission;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
public class PermissionHelper { public class PermissionHelper {
private final AppCompatActivity activity; private final AppCompatActivity activity;
private CallBackListener listener; private CallBackListener listener;
private PreferencesHelper pf; private PreferencesHelper pf;
public PermissionHelper(AppCompatActivity activity) { public PermissionHelper(AppCompatActivity activity) {
this.activity = activity; this.activity = activity;
} }
public void setListener(CallBackListener listener) { public void setListener(CallBackListener listener) {
this.listener = listener; this.listener = listener;
} }
public void askPermissions() { public void askPermissions() {
pf = PreferencesHelper.getInstance(activity); pf = PreferencesHelper.getInstance(activity);
askStoragePermissions(); askStoragePermissions();
} }
// permission block // permission block
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
private void askStoragePermissions() { private void askStoragePermissions() {
TedRx2Permission.with(activity) TedRx2Permission.with(activity)
.setPermissions(WRITE_EXTERNAL_STORAGE) .setPermissions(WRITE_EXTERNAL_STORAGE)
.request() .request()
.subscribe(tedPermissionResult -> { .subscribe(tedPermissionResult -> {
if (tedPermissionResult.isGranted()) { if (tedPermissionResult.isGranted()) {
listener.onEvent(true); listener.onEvent(true);
} else { } else {
if (TedRx2Permission.canRequestPermission(activity, WRITE_EXTERNAL_STORAGE)) if (TedRx2Permission.canRequestPermission(activity, WRITE_EXTERNAL_STORAGE))
askStorageRationalePermissions(); askStorageRationalePermissions();
else askStorageWhenDoNotShow(); else askStorageWhenDoNotShow();
} }
}); });
} }
// storage permissions block // storage permissions block
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
private void askStorageRationalePermissions() { private void askStorageRationalePermissions() {
TedRx2Permission.with(activity) TedRx2Permission.with(activity)
.setRationaleMessage(R.string.explain) .setRationaleMessage(R.string.explain)
.setDeniedMessage(R.string.denied) .setDeniedMessage(R.string.denied)
.setDeniedCloseButtonText(R.string.close_game) .setDeniedCloseButtonText(R.string.close_game)
.setGotoSettingButtonText(R.string.settings) .setGotoSettingButtonText(R.string.settings)
.setPermissions(WRITE_EXTERNAL_STORAGE) .setPermissions(WRITE_EXTERNAL_STORAGE)
.request() .request()
.subscribe(tedPermissionResult -> { .subscribe(tedPermissionResult -> {
if (tedPermissionResult.isGranted()) { listener.onEvent(tedPermissionResult.isGranted());
listener.onEvent(true); });
} else { }
listener.onEvent(false);
}
});
}
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
private void askStorageWhenDoNotShow() { private void askStorageWhenDoNotShow() {
TedRx2Permission.with(activity) TedRx2Permission.with(activity)
.setDeniedMessage(R.string.denied) .setDeniedMessage(R.string.denied)
.setDeniedCloseButtonText(R.string.close_game) .setDeniedCloseButtonText(R.string.close_game)
.setGotoSettingButtonText(R.string.settings) .setGotoSettingButtonText(R.string.settings)
.setPermissions(WRITE_EXTERNAL_STORAGE) .setPermissions(WRITE_EXTERNAL_STORAGE)
.request() .request()
.subscribe(tedPermissionResult -> { .subscribe(tedPermissionResult -> {
if (tedPermissionResult.isGranted()) { listener.onEvent(tedPermissionResult.isGranted());
listener.onEvent(true); });
} else { }
listener.onEvent(false);
}
});
}
} }

View File

@ -26,92 +26,92 @@ import android.content.SharedPreferences;
import com.multicraft.game.RemoteSettings; import com.multicraft.game.RemoteSettings;
public class PreferencesHelper { public class PreferencesHelper {
public static final String TAG_SHORTCUT_EXIST = "createShortcut"; public static final String TAG_SHORTCUT_EXIST = "createShortcut";
public static final String TAG_BUILD_NUMBER = "buildNumber"; public static final String TAG_BUILD_NUMBER = "buildNumber";
public static final String TAG_LAUNCH_TIMES = "launchTimes"; public static final String TAG_LAUNCH_TIMES = "launchTimes";
public static final String TAG_CONSENT_ASKED = "consentAsked"; public static final String TAG_CONSENT_ASKED = "consentAsked";
public static final String TAG_COPY_OLD_WORLDS = "copyOldWorlds"; public static final String TAG_COPY_OLD_WORLDS = "copyOldWorlds";
public static final String IS_LOADED = "interstitialLoaded"; public static final String IS_LOADED = "interstitialLoaded";
public static final String RV_LOADED = "rewardedVideoLoaded"; public static final String RV_LOADED = "rewardedVideoLoaded";
private static final String ADS_DELAY = "adsDelay"; private static final String ADS_DELAY = "adsDelay";
private static final String ADS_REPEAT = "adsRepeat"; private static final String ADS_REPEAT = "adsRepeat";
private static final String ADS_ENABLE = "adsEnable"; private static final String ADS_ENABLE = "adsEnable";
private static final String SETTINGS = "MultiCraftSettings"; private static final String SETTINGS = "MultiCraftSettings";
private static PreferencesHelper instance; private static PreferencesHelper instance;
private static SharedPreferences sharedPreferences; private static SharedPreferences sharedPreferences;
private PreferencesHelper(Context context) { private PreferencesHelper(Context context) {
sharedPreferences = context.getSharedPreferences(SETTINGS, Context.MODE_PRIVATE); sharedPreferences = context.getSharedPreferences(SETTINGS, Context.MODE_PRIVATE);
} }
public static PreferencesHelper getInstance(Context context) { public static PreferencesHelper getInstance(Context context) {
if (instance == null) { if (instance == null) {
synchronized (PreferencesHelper.class) { synchronized (PreferencesHelper.class) {
if (instance == null) if (instance == null)
instance = new PreferencesHelper(context.getApplicationContext()); instance = new PreferencesHelper(context.getApplicationContext());
} }
} }
return instance; return instance;
} }
public boolean isCreateShortcut() { public boolean isCreateShortcut() {
return sharedPreferences.getBoolean(TAG_SHORTCUT_EXIST, false); return sharedPreferences.getBoolean(TAG_SHORTCUT_EXIST, false);
} }
public boolean isInterstitialLoaded() { public boolean isInterstitialLoaded() {
return sharedPreferences.getBoolean(IS_LOADED, false); return sharedPreferences.getBoolean(IS_LOADED, false);
} }
public boolean isVideoLoaded() { public boolean isVideoLoaded() {
return sharedPreferences.getBoolean(RV_LOADED, false); return sharedPreferences.getBoolean(RV_LOADED, false);
} }
public boolean isAskConsent() { public boolean isAskConsent() {
return sharedPreferences.getBoolean(TAG_CONSENT_ASKED, true); return sharedPreferences.getBoolean(TAG_CONSENT_ASKED, true);
} }
public boolean isWorldsCopied() { public boolean isWorldsCopied() {
return sharedPreferences.getBoolean(TAG_COPY_OLD_WORLDS, false); return sharedPreferences.getBoolean(TAG_COPY_OLD_WORLDS, false);
} }
public String getBuildNumber() { public String getBuildNumber() {
return sharedPreferences.getString(TAG_BUILD_NUMBER, "0"); return sharedPreferences.getString(TAG_BUILD_NUMBER, "0");
} }
public int getLaunchTimes() { public int getLaunchTimes() {
return sharedPreferences.getInt(TAG_LAUNCH_TIMES, 0); return sharedPreferences.getInt(TAG_LAUNCH_TIMES, 0);
} }
public int getAdsDelay() { public int getAdsDelay() {
return sharedPreferences.getInt(ADS_DELAY, 600); return sharedPreferences.getInt(ADS_DELAY, 600);
} }
public int getAdsRepeat() { public int getAdsRepeat() {
return sharedPreferences.getInt(ADS_REPEAT, 900); return sharedPreferences.getInt(ADS_REPEAT, 900);
} }
public boolean isAdsEnable() { public boolean isAdsEnable() {
return sharedPreferences.getBoolean(ADS_ENABLE, true); return sharedPreferences.getBoolean(ADS_ENABLE, true);
} }
public void saveSettings(String tag, boolean bool) { public void saveSettings(String tag, boolean bool) {
sharedPreferences.edit().putBoolean(tag, bool).apply(); sharedPreferences.edit().putBoolean(tag, bool).apply();
} }
public void saveSettings(String tag, String value) { public void saveSettings(String tag, String value) {
sharedPreferences.edit().putString(tag, value).apply(); sharedPreferences.edit().putString(tag, value).apply();
} }
public void saveSettings(String tag, int value) { public void saveSettings(String tag, int value) {
sharedPreferences.edit().putInt(tag, value).apply(); sharedPreferences.edit().putInt(tag, value).apply();
} }
public void saveAdsSettings(RemoteSettings remoteSettings) { public void saveAdsSettings(RemoteSettings remoteSettings) {
int delay = remoteSettings.getAdsDelay(); int delay = remoteSettings.getAdsDelay();
int repeat = remoteSettings.getAdsRepeat(); int repeat = remoteSettings.getAdsRepeat();
if (delay != -1) saveSettings(ADS_DELAY, delay); if (delay != -1) saveSettings(ADS_DELAY, delay);
if (repeat != -1) saveSettings(ADS_REPEAT, repeat); if (repeat != -1) saveSettings(ADS_REPEAT, repeat);
saveSettings(ADS_ENABLE, remoteSettings.isAdsEnabled()); saveSettings(ADS_ENABLE, remoteSettings.isAdsEnabled());
} }
} }

View File

@ -47,79 +47,79 @@ import static com.multicraft.game.helpers.ApiLevelHelper.isGreaterOrEqualKitkat;
import static com.multicraft.game.helpers.PreferencesHelper.TAG_SHORTCUT_EXIST; import static com.multicraft.game.helpers.PreferencesHelper.TAG_SHORTCUT_EXIST;
public class Utilities { public class Utilities {
private static final String appPackage = BuildConfig.APPLICATION_ID; private static final String appPackage = BuildConfig.APPLICATION_ID;
private static boolean isInternetAvailable(String url) { private static boolean isInternetAvailable(String url) {
try { try {
HttpURLConnection urlc = HttpURLConnection urlc =
(HttpURLConnection) new URL(url).openConnection(); (HttpURLConnection) new URL(url).openConnection();
urlc.setRequestProperty("Connection", "close"); urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(2000); urlc.setConnectTimeout(2000);
urlc.connect(); urlc.connect();
int ResponseCode = urlc.getResponseCode(); int ResponseCode = urlc.getResponseCode();
return ResponseCode == HttpURLConnection.HTTP_NO_CONTENT || return ResponseCode == HttpURLConnection.HTTP_NO_CONTENT ||
ResponseCode == HttpURLConnection.HTTP_OK; ResponseCode == HttpURLConnection.HTTP_OK;
} catch (IOException e) { } catch (IOException e) {
return false; return false;
} }
} }
public static boolean isReachable() { public static boolean isReachable() {
return isInternetAvailable("http://clients3.google.com/generate_204") || return isInternetAvailable("http://clients3.google.com/generate_204") ||
isInternetAvailable("http://servers.multicraft.world"); isInternetAvailable("http://servers.multicraft.world");
} }
public static boolean deleteFiles(List<String> files) { public static boolean deleteFiles(List<String> files) {
boolean result = true; boolean result = true;
for (String f : files) { for (String f : files) {
File file = new File(f); File file = new File(f);
if (file.exists()) { if (file.exists()) {
result = result && FileUtils.deleteQuietly(file); result = result && FileUtils.deleteQuietly(file);
} }
} }
return result; return result;
} }
public static String getStoreUrl() { public static String getStoreUrl() {
String store = "market://details?id="; String store = "market://details?id=";
return store + appPackage; return store + appPackage;
} }
public static void makeFullScreen(Activity activity) { public static void makeFullScreen(Activity activity) {
if (isGreaterOrEqualKitkat()) if (isGreaterOrEqualKitkat())
activity.getWindow().getDecorView().setSystemUiVisibility( activity.getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
} }
public static Drawable getIcon(Activity activity) { public static Drawable getIcon(Activity activity) {
try { try {
return activity.getPackageManager().getApplicationIcon(activity.getPackageName()); return activity.getPackageManager().getApplicationIcon(activity.getPackageName());
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
Bugsnag.notify(e); Bugsnag.notify(e);
return activity.getResources().getDrawable(R.mipmap.ic_launcher); return activity.getResources().getDrawable(R.mipmap.ic_launcher);
} }
} }
public static void addShortcut(Activity activity) { public static void addShortcut(Activity activity) {
ActivityManager activityManager = ActivityManager activityManager =
(ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE); (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
int size = 0; int size = 0;
if (activityManager != null) if (activityManager != null)
size = activityManager.getLauncherLargeIconSize(); size = activityManager.getLauncherLargeIconSize();
Bitmap shortcutIconBitmap = ((BitmapDrawable) getIcon(activity)).getBitmap(); Bitmap shortcutIconBitmap = ((BitmapDrawable) getIcon(activity)).getBitmap();
if (shortcutIconBitmap.getWidth() < size) if (shortcutIconBitmap.getWidth() < size)
shortcutIconBitmap = Bitmap.createScaledBitmap(shortcutIconBitmap, size, size, true); shortcutIconBitmap = Bitmap.createScaledBitmap(shortcutIconBitmap, size, size, true);
PreferencesHelper.getInstance(activity).saveSettings(TAG_SHORTCUT_EXIST, true); PreferencesHelper.getInstance(activity).saveSettings(TAG_SHORTCUT_EXIST, true);
Intent shortcutIntent = new Intent(activity, MainActivity.class); Intent shortcutIntent = new Intent(activity, MainActivity.class);
shortcutIntent.setAction(Intent.ACTION_MAIN); shortcutIntent.setAction(Intent.ACTION_MAIN);
Intent addIntent = new Intent(); Intent addIntent = new Intent();
addIntent.putExtra("duplicate", false); addIntent.putExtra("duplicate", false);
addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); 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_NAME, activity.getResources().getString(R.string.app_name));
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, shortcutIconBitmap); addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, shortcutIconBitmap);
addIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT"); addIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
activity.sendBroadcast(addIntent); activity.sendBroadcast(addIntent);
} }
} }

View File

@ -53,155 +53,155 @@ import static com.multicraft.game.MainActivity.UPDATE_LINK;
import static com.multicraft.game.helpers.Utilities.getStoreUrl; import static com.multicraft.game.helpers.Utilities.getStoreUrl;
public class VersionManagerHelper { public class VersionManagerHelper {
private static final String JSON_VERSION_CODE = "version_code"; 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_VERSION_CODE_BAD = "version_code_bad";
private static final String JSON_PACKAGE = "package"; private static final String JSON_PACKAGE = "package";
private static final String JSON_CONTENT_RU = "content_ru"; private static final String JSON_CONTENT_RU = "content_ru";
private static final String JSON_CONTENT_EN = "content_en"; private static final String JSON_CONTENT_EN = "content_en";
private static final String JSON_ADS_DELAY = "ads_delay"; private static final String JSON_ADS_DELAY = "ads_delay";
private static final String JSON_ADS_REPEAT = "ads_repeat"; private static final String JSON_ADS_REPEAT = "ads_repeat";
private static final String JSON_ADS_ENABLE = "ads_enable"; private static final String JSON_ADS_ENABLE = "ads_enable";
private final CustomTagHandler customTagHandler; private final CustomTagHandler customTagHandler;
private final String PREF_REMINDER_TIME = "w.reminder.time"; private final String PREF_REMINDER_TIME = "w.reminder.time";
private final AppCompatActivity activity; private final AppCompatActivity activity;
private final int versionCode = BuildConfig.VERSION_CODE; private final int versionCode = BuildConfig.VERSION_CODE;
private String message, updateUrl; private String message, updateUrl;
public VersionManagerHelper(AppCompatActivity act) { public VersionManagerHelper(AppCompatActivity act) {
this.activity = act; this.activity = act;
this.customTagHandler = new CustomTagHandler(); this.customTagHandler = new CustomTagHandler();
} }
public boolean isCheckVersion() { public boolean isCheckVersion() {
long currentTimeStamp = Calendar.getInstance().getTimeInMillis(); long currentTimeStamp = Calendar.getInstance().getTimeInMillis();
long reminderTimeStamp = getReminderTime(); long reminderTimeStamp = getReminderTime();
return currentTimeStamp > reminderTimeStamp; return currentTimeStamp > reminderTimeStamp;
} }
private boolean isBadVersion(List<Integer> badVersions) { private boolean isBadVersion(List<Integer> badVersions) {
return badVersions.contains(versionCode); return badVersions.contains(versionCode);
} }
private List<Integer> convertToList(JSONArray badVersions) throws JSONException { private List<Integer> convertToList(JSONArray badVersions) throws JSONException {
List<Integer> badVersionList = new ArrayList<>(); List<Integer> badVersionList = new ArrayList<>();
if (badVersions != null) { if (badVersions != null) {
for (int i = 0; i < badVersions.length(); i++) for (int i = 0; i < badVersions.length(); i++)
badVersionList.add(badVersions.getInt(i)); badVersionList.add(badVersions.getInt(i));
} }
return badVersionList; return badVersionList;
} }
private RemoteSettings parseJson(String result) throws JSONException { private RemoteSettings parseJson(String result) throws JSONException {
RemoteSettings remoteSettings = new RemoteSettings(); RemoteSettings remoteSettings = new RemoteSettings();
PreferencesHelper pf = PreferencesHelper.getInstance(activity); PreferencesHelper pf = PreferencesHelper.getInstance(activity);
if (!result.startsWith("{")) // for response who append with unknown char if (!result.startsWith("{")) // for response who append with unknown char
result = result.substring(1); result = result.substring(1);
String mResult = result; String mResult = result;
// json format from server: // json format from server:
JSONObject json = new JSONObject(new JSONTokener(mResult)); JSONObject json = new JSONObject(new JSONTokener(mResult));
remoteSettings.setVersionCode(json.getInt(JSON_VERSION_CODE)); remoteSettings.setVersionCode(json.getInt(JSON_VERSION_CODE));
remoteSettings.setBadVersionCodes(convertToList(json.getJSONArray(JSON_VERSION_CODE_BAD))); remoteSettings.setBadVersionCodes(convertToList(json.getJSONArray(JSON_VERSION_CODE_BAD)));
String lang = Locale.getDefault().getLanguage(); String lang = Locale.getDefault().getLanguage();
String content = lang.equals("ru") ? JSON_CONTENT_RU : JSON_CONTENT_EN; String content = lang.equals("ru") ? JSON_CONTENT_RU : JSON_CONTENT_EN;
remoteSettings.setContent(json.getString(content)); remoteSettings.setContent(json.getString(content));
setMessage(remoteSettings.getContent()); setMessage(remoteSettings.getContent());
remoteSettings.setPackageName(json.getString(JSON_PACKAGE)); remoteSettings.setPackageName(json.getString(JSON_PACKAGE));
setUpdateUrl("market://details?id=" + remoteSettings.getPackageName()); setUpdateUrl("market://details?id=" + remoteSettings.getPackageName());
remoteSettings.setAdsDelay(json.getInt(JSON_ADS_DELAY)); remoteSettings.setAdsDelay(json.getInt(JSON_ADS_DELAY));
remoteSettings.setAdsRepeat(json.getInt(JSON_ADS_REPEAT)); remoteSettings.setAdsRepeat(json.getInt(JSON_ADS_REPEAT));
remoteSettings.setAdsEnabled(json.getBoolean(JSON_ADS_ENABLE)); remoteSettings.setAdsEnabled(json.getBoolean(JSON_ADS_ENABLE));
pf.saveAdsSettings(remoteSettings); pf.saveAdsSettings(remoteSettings);
return remoteSettings; return remoteSettings;
} }
public boolean isShow(String result) { public boolean isShow(String result) {
if (result.equals("{}")) return false; if (result.equals("{}")) return false;
RemoteSettings remoteSettings; RemoteSettings remoteSettings;
try { try {
remoteSettings = parseJson(result); remoteSettings = parseJson(result);
} catch (JSONException e) { } catch (JSONException e) {
return false; return false;
} }
return (versionCode < remoteSettings.getVersionCode()) || return (versionCode < remoteSettings.getVersionCode()) ||
isBadVersion(remoteSettings.getBadVersionCodes()); isBadVersion(remoteSettings.getBadVersionCodes());
} }
public String getJson() { public String getJson() {
OkHttpClient client = new OkHttpClient.Builder() OkHttpClient client = new OkHttpClient.Builder()
.callTimeout(3000, TimeUnit.MILLISECONDS) .callTimeout(3000, TimeUnit.MILLISECONDS)
.build(); .build();
Request request = new Request.Builder() Request request = new Request.Builder()
.url(UPDATE_LINK) .url(UPDATE_LINK)
.build(); .build();
try { try {
Response response = client.newCall(request).execute(); Response response = client.newCall(request).execute();
return response.body().string(); return response.body().string();
} catch (IOException | NullPointerException e) { } catch (IOException | NullPointerException e) {
// nothing // nothing
} }
return "{}"; return "{}";
} }
public String getMessage() { public String getMessage() {
String defaultMessage = "What's new?"; String defaultMessage = "What's new?";
return message != null ? message : defaultMessage; return message != null ? message : defaultMessage;
} }
private void setMessage(String message) { private void setMessage(String message) {
this.message = message; this.message = message;
} }
public String getUpdateUrl() { public String getUpdateUrl() {
return updateUrl != null ? updateUrl : getStoreUrl(); return updateUrl != null ? updateUrl : getStoreUrl();
} }
private void setUpdateUrl(String updateUrl) { private void setUpdateUrl(String updateUrl) {
this.updateUrl = updateUrl; this.updateUrl = updateUrl;
} }
public void updateNow(String url) { public void updateNow(String url) {
if (url != null) { if (url != null) {
try { try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
activity.startActivity(intent); activity.startActivity(intent);
} catch (Exception e) { } catch (Exception e) {
Bugsnag.notify(e); Bugsnag.notify(e);
} }
} }
} }
public void remindMeLater() { public void remindMeLater() {
Calendar c = Calendar.getInstance(); Calendar c = Calendar.getInstance();
c.add(Calendar.MINUTE, 1); c.add(Calendar.MINUTE, 1);
long reminderTimeStamp = c.getTimeInMillis(); long reminderTimeStamp = c.getTimeInMillis();
setReminderTime(reminderTimeStamp); setReminderTime(reminderTimeStamp);
} }
private long getReminderTime() { private long getReminderTime() {
return PreferenceManager.getDefaultSharedPreferences(activity).getLong( return PreferenceManager.getDefaultSharedPreferences(activity).getLong(
PREF_REMINDER_TIME, 0); PREF_REMINDER_TIME, 0);
} }
private void setReminderTime(long reminderTimeStamp) { private void setReminderTime(long reminderTimeStamp) {
PreferenceManager.getDefaultSharedPreferences(activity).edit().putLong( PreferenceManager.getDefaultSharedPreferences(activity).edit().putLong(
PREF_REMINDER_TIME, reminderTimeStamp).apply(); PREF_REMINDER_TIME, reminderTimeStamp).apply();
} }
public CustomTagHandler getCustomTagHandler() { public CustomTagHandler getCustomTagHandler() {
return customTagHandler; return customTagHandler;
} }
private static class CustomTagHandler implements Html.TagHandler { private static class CustomTagHandler implements Html.TagHandler {
@Override @Override
public void handleTag(boolean opening, String tag, Editable output, public void handleTag(boolean opening, String tag, Editable output,
XMLReader xmlReader) { XMLReader xmlReader) {
// you may add more tag handler which are not supported by android here // you may add more tag handler which are not supported by android here
if ("li".equals(tag)) { if ("li".equals(tag)) {
if (opening) if (opening)
output.append(" \u2022 "); output.append(" \u2022 ");
else else
output.append("\n"); output.append("\n");
} }
} }
} }
} }

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android" <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/background" android:src="@drawable/background"
android:tileMode="repeat" /> android:tileMode="repeat" />

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" <shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"> android:shape="rectangle">
<solid android:color="@android:color/white" /> <solid android:color="@android:color/white" />
<corners android:radius="12dp" /> <corners android:radius="12dp" />
</shape> </shape>

View File

@ -1,10 +1,10 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <selector xmlns:android="http://schemas.android.com/apk/res/android">
<item> <item>
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<solid android:color="#FFFFFF" /> <solid android:color="#FFFFFF" />
<corners android:radius="8dp" /> <corners android:radius="8dp" />
<padding android:left="8dp" /> <padding android:left="8dp" />
<stroke android:width="2dp" android:color="#59000000" /> <stroke android:width="2dp" android:color="#59000000" />
</shape> </shape>
</item> </item>
</selector> </selector>

View File

@ -1,27 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item> <item>
<shape> <shape>
<stroke <stroke
android:width="2.5dp" android:width="2.5dp"
android:color="#000000" /> android:color="#000000" />
<padding <padding
android:bottom="3dp" android:bottom="3dp"
android:left="3dp" android:left="3dp"
android:right="3dp" android:right="3dp"
android:top="3dp" /> android:top="3dp" />
<corners android:radius="40dip" /> <corners android:radius="40dip" />
<gradient <gradient
android:endColor="#6a6a6a" android:endColor="#6a6a6a"
android:startColor="#6a6a6a" /> android:startColor="#6a6a6a" />
</shape> </shape>
</item> </item>
<item> <item>
<clip> <clip>
<shape> <shape>
<corners android:radius="40dip" /> <corners android:radius="40dip" />
</shape> </shape>
</clip> </clip>
</item> </item>
</layer-list> </layer-list>

View File

@ -1,170 +1,170 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp" android:width="108dp"
android:height="108dp" android:height="108dp"
android:viewportWidth="108" android:viewportWidth="108"
android:viewportHeight="108"> android:viewportHeight="108">
<path <path
android:fillColor="#008577" android:fillColor="#008577"
android:pathData="M0,0h108v108h-108z" /> android:pathData="M0,0h108v108h-108z" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M9,0L9,108" android:pathData="M9,0L9,108"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M19,0L19,108" android:pathData="M19,0L19,108"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M29,0L29,108" android:pathData="M29,0L29,108"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M39,0L39,108" android:pathData="M39,0L39,108"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M49,0L49,108" android:pathData="M49,0L49,108"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M59,0L59,108" android:pathData="M59,0L59,108"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M69,0L69,108" android:pathData="M69,0L69,108"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M79,0L79,108" android:pathData="M79,0L79,108"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M89,0L89,108" android:pathData="M89,0L89,108"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M99,0L99,108" android:pathData="M99,0L99,108"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M0,9L108,9" android:pathData="M0,9L108,9"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M0,19L108,19" android:pathData="M0,19L108,19"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M0,29L108,29" android:pathData="M0,29L108,29"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M0,39L108,39" android:pathData="M0,39L108,39"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M0,49L108,49" android:pathData="M0,49L108,49"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M0,59L108,59" android:pathData="M0,59L108,59"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M0,69L108,69" android:pathData="M0,69L108,69"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M0,79L108,79" android:pathData="M0,79L108,79"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M0,89L108,89" android:pathData="M0,89L108,89"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M0,99L108,99" android:pathData="M0,99L108,99"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M19,29L89,29" android:pathData="M19,29L89,29"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M19,39L89,39" android:pathData="M19,39L89,39"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M19,49L89,49" android:pathData="M19,49L89,49"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M19,59L89,59" android:pathData="M19,59L89,59"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M19,69L89,69" android:pathData="M19,69L89,69"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M19,79L89,79" android:pathData="M19,79L89,79"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M29,19L29,89" android:pathData="M29,19L29,89"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M39,19L39,89" android:pathData="M39,19L39,89"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M49,19L49,89" android:pathData="M49,19L49,89"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M59,19L59,89" android:pathData="M59,19L59,89"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M69,19L69,89" android:pathData="M69,19L69,89"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
<path <path
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M79,19L79,89" android:pathData="M79,19L79,89"
android:strokeWidth="0.8" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" /> android:strokeColor="#33FFFFFF" />
</vector> </vector>

View File

@ -1,37 +1,37 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<ProgressBar <ProgressBar
android:id="@+id/PB1" android:id="@+id/PB1"
style="@style/CustomProgressBar" style="@style/CustomProgressBar"
android:layout_width="400dp" android:layout_width="400dp"
android:layout_height="45dp" android:layout_height="45dp"
android:layout_centerInParent="true" android:layout_centerInParent="true"
android:layout_marginLeft="120dp" android:layout_marginLeft="120dp"
android:layout_marginRight="120dp" android:layout_marginRight="120dp"
android:indeterminate="false" android:indeterminate="false"
android:max="100" android:max="100"
android:visibility="gone" /> android:visibility="gone" />
<ProgressBar <ProgressBar
android:id="@+id/PB2" android:id="@+id/PB2"
style="Widget.AppCompat.ProgressBar" style="Widget.AppCompat.ProgressBar"
android:layout_width="75dp" android:layout_width="75dp"
android:layout_height="75dp" android:layout_height="75dp"
android:layout_centerInParent="true" android:layout_centerInParent="true"
android:indeterminate="true" android:indeterminate="true"
android:visibility="gone" /> android:visibility="gone" />
<TextView <TextView
android:id="@+id/tv_progress" android:id="@+id/tv_progress"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/PB2" android:layout_below="@id/PB2"
android:layout_centerInParent="true" android:layout_centerInParent="true"
android:text="@string/loading" android:text="@string/loading"
android:textColor="#fefefe" android:textColor="#fefefe"
android:textSize="14sp" android:textSize="14sp"
android:visibility="gone" /> android:visibility="gone" />
</RelativeLayout> </RelativeLayout>

View File

@ -1,50 +1,50 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:padding="10dp"> android:padding="10dp">
<TextView <TextView
android:id="@+id/ratingTitle" android:id="@+id/ratingTitle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/rate_dialog_title" android:text="@string/rate_dialog_title"
android:textSize="20sp" android:textSize="20sp"
android:textStyle="bold" /> android:textStyle="bold" />
<RatingBar <RatingBar
android:id="@+id/ratingBar" android:id="@+id/ratingBar"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:numStars="5" android:numStars="5"
android:stepSize="1" /> android:stepSize="1" />
<EditText <EditText
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp" android:layout_height="60dp"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:background="@drawable/custom_edittext_rounded" android:background="@drawable/custom_edittext_rounded"
android:clickable="false" android:clickable="false"
android:cursorVisible="false" android:cursorVisible="false"
android:focusable="false" android:focusable="false"
android:focusableInTouchMode="false" android:focusableInTouchMode="false"
android:hint="@string/rate_description" android:hint="@string/rate_description"
android:importantForAutofill="no" android:importantForAutofill="no"
android:inputType="text" android:inputType="text"
android:textSize="14sp" /> android:textSize="14sp" />
<Button <Button
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="end" android:layout_gravity="end"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:enabled="false" android:enabled="false"
android:text="@string/rate_submit" android:text="@string/rate_submit"
android:textColor="#008c80" android:textColor="#008c80"
android:textStyle="bold" /> android:textStyle="bold" />
</LinearLayout> </LinearLayout>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" /> <background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" /> <foreground android:drawable="@mipmap/ic_launcher_foreground" />
</adaptive-icon> </adaptive-icon>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" /> <background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" /> <foreground android:drawable="@mipmap/ic_launcher_foreground" />
</adaptive-icon> </adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

View File

@ -1,42 +1,42 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- подготовка к запуску --> <!-- подготовка к запуску -->
<string name="preparing">Подготовка к запуску&#8230;</string> <string name="preparing">Подготовка к запуску&#8230;</string>
<string name="loading">Загрузка&#8230;</string> <string name="loading">Загрузка&#8230;</string>
<string name="loadingp">Загрузка&#8230; %d%%</string> <string name="loadingp">Загрузка&#8230; %d%%</string>
<string name="downloading">Загрузка новой версии&#8230;</string> <string name="downloading">Загрузка новой версии&#8230;</string>
<string name="downloadingp">Загрузка новой версии&#8230; %d%%</string> <string name="downloadingp">Загрузка новой версии&#8230; %d%%</string>
<string name="notification_title">Загрузка MultiCraft</string> <string name="notification_title">Загрузка MultiCraft</string>
<string name="notification_description">Осталось меньше минуты&#8230;</string> <string name="notification_description">Осталось меньше минуты&#8230;</string>
<string name="restart">Произошла ошибка, игра будет перезапущена автоматически</string> <string name="restart">Произошла ошибка, игра будет перезапущена автоматически</string>
<string name="no_space">Недостаточно места для записи файлов игры, пожалуйста освободите место в памяти</string> <string name="no_space">Недостаточно места для записи файлов игры, пожалуйста освободите место в памяти</string>
<!-- разрешения --> <!-- разрешения -->
<string name="explain">Разрешение на запись необходимо для распаковки текстур и игровых файлов.</string> <string name="explain">Разрешение на запись необходимо для распаковки текстур и игровых файлов.</string>
<string name="location">Доступ к местоположению обеспечивает Вам лучшее взаимодействие с игрой</string> <string name="location">Доступ к местоположению обеспечивает Вам лучшее взаимодействие с игрой</string>
<string name="close_game">Закрыть игру</string> <string name="close_game">Закрыть игру</string>
<string name="settings">Настройки</string> <string name="settings">Настройки</string>
<string name="denied">Вы не можете играть в MultiCraft без разрешения на запись.\nПожалуйста, включите его в [Настройки] -> [Разрешения]></string> <string name="denied">Вы не можете играть в MultiCraft без разрешения на запись.\nПожалуйста, включите его в [Настройки] -> [Разрешения]></string>
<!-- диалог оценки --> <!-- диалог оценки -->
<string name="rate_dialog_title">Оцените MultiCraft!</string> <string name="rate_dialog_title">Оцените MultiCraft!</string>
<string name="rate_description">Поделитесь впечатлениями</string> <string name="rate_description">Поделитесь впечатлениями</string>
<string name="rate_submit">ОЦЕНИТЬ</string> <string name="rate_submit">ОЦЕНИТЬ</string>
<string name="sad">Нам жаль, что Вам не понравилась игра!</string> <string name="sad">Нам жаль, что Вам не понравилась игра!</string>
<string name="thank">Пожалуйста, оставьте отзыв для нас. Спасибо!</string> <string name="thank">Пожалуйста, оставьте отзыв для нас. Спасибо!</string>
<!-- диалог обновления --> <!-- диалог обновления -->
<string name="available">Доступна Новая Версия!</string> <string name="available">Доступна Новая Версия!</string>
<string name="ignore">Игнорировать</string> <string name="ignore">Игнорировать</string>
<string name="later">Позже</string> <string name="later">Позже</string>
<string name="update">Обновить</string> <string name="update">Обновить</string>
<!-- диалог отсутствия подключения --> <!-- диалог отсутствия подключения -->
<string name="conn_message">Для полноценной игры, MultiCraft требует подключение к интернету.\nВ противном случае невозможно обновление игры, а так же не доступен мультиплеер!</string> <string name="conn_message">Для полноценной игры, MultiCraft требует подключение к интернету.\nВ противном случае невозможно обновление игры, а так же не доступен мультиплеер!</string>
<string name="conn_mobile">3G/4G</string> <string name="conn_mobile">3G/4G</string>
<!-- диалог удаления старой версии --> <!-- диалог удаления старой версии -->
<string name="del_message">Удалить старую версию MultiCraft?</string> <string name="del_message">Удалить старую версию MultiCraft?</string>
</resources> </resources>

View File

@ -1,51 +1,52 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" translatable="false">MultiCraft</string> <string name="app_name" translatable="false">MultiCraft</string>
<!-- preparation for start --> <!-- preparation for start -->
<string name="preparing">Preparing to launch&#8230;</string> <string name="preparing">Preparing to launch&#8230;</string>
<string name="loading">Loading&#8230;</string> <string name="loading">Loading&#8230;</string>
<string name="loadingp">Loading&#8230; %d%%</string> <string name="loadingp">Loading&#8230; %d%%</string>
<string name="downloading">Downloading new version&#8230;</string> <string name="downloading">Downloading new version&#8230;</string>
<string name="downloadingp">Downloading new version&#8230; %d%%</string> <string name="downloadingp">Downloading new version&#8230; %d%%</string>
<string name="notification_title">Loading MultiCraft</string> <string name="notification_title">Loading MultiCraft</string>
<string name="notification_description">Less than 1 minute&#8230;</string> <string name="notification_description">Less than 1 minute&#8230;</string>
<string name="restart">Unexpected issue, the game will be restarted automatically</string> <string name="restart">Unexpected issue, the game will be restarted automatically</string>
<string name="no_space">No space left for game files, please free space in the memory</string> <string name="no_space">No space left for game files, please free space in the memory</string>
<string name="ok" translatable="false">OK</string>
<!-- permission block --> <!-- permission block -->
<string name="explain">Storage permissions is necessary to unpack textures and game data.</string> <string name="explain">Storage permissions is necessary to unpack textures and game data.</string>
<string name="location">Location permission provide you better interaction with game</string> <string name="location">Location permission provide you better interaction with game</string>
<string name="close_game">Close game</string> <string name="close_game">Close game</string>
<string name="settings">App settings</string> <string name="settings">App settings</string>
<string name="denied">You cannot play MultiCraft without storage permission.\nPlease turn on it at [Settings] -> [Permissions]></string> <string name="denied">You cannot play MultiCraft without storage permission.\nPlease turn on it at [Settings] -> [Permissions]></string>
<!-- rate dialog --> <!-- rate dialog -->
<string name="rate_dialog_title">Please, rate MultiCraft!</string> <string name="rate_dialog_title">Please, rate MultiCraft!</string>
<string name="rate_description">Describe your experience</string> <string name="rate_description">Describe your experience</string>
<string name="rate_submit">SUBMIT</string> <string name="rate_submit">SUBMIT</string>
<string name="sad">We are sorry that you did not like the game!</string> <string name="sad">We are sorry that you did not like the game!</string>
<string name="thank">Please leave a review for us. Thank you!</string> <string name="thank">Please leave a review for us. Thank you!</string>
<!-- update dialog --> <!-- update dialog -->
<string name="available">New Version Available!</string> <string name="available">New Version Available!</string>
<string name="update">Update</string> <string name="update">Update</string>
<string name="later">Later</string> <string name="later">Later</string>
<string name="ignore">Ignore</string> <string name="ignore">Ignore</string>
<!-- no connection dialog --> <!-- no connection dialog -->
<string name="conn_message">MultiCraft requires an internet connection to use all game features.\nOtherwise, you will not get updates and multiplayer will be not available!</string> <string name="conn_message">MultiCraft requires an internet connection to use all game features.\nOtherwise, you will not get updates and multiplayer will be not available!</string>
<string name="conn_wifi" translatable="false">Wi-Fi</string> <string name="conn_wifi" translatable="false">Wi-Fi</string>
<string name="conn_mobile">Mobile Data</string> <string name="conn_mobile">Mobile Data</string>
<!-- uninstall old version dialog --> <!-- uninstall old version dialog -->
<string name="del_message">Uninstall an old version of MultiCraft?</string> <string name="del_message">Uninstall an old version of MultiCraft?</string>
<!-- GDPR --> <!-- GDPR -->
<string name="gdpr_main_text" translatable="false"><b>We care about your privacy and data security. We keep this app free by showing ads.\n<big>Can we continue to use your data to tailor ads for you?</big></b>\n\n<small>Our 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 <a href="https://www.appodeal.com/privacy-policy">Privacy Policy</a>.</small></string> <string name="gdpr_main_text" translatable="false"><b>We care about your privacy and data security. We keep this app free by showing ads.\n<big>Can we continue to use your data to tailor ads for you?</big></b>\n\n<small>Our 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 <a href="https://www.appodeal.com/privacy-policy">Privacy Policy</a>.</small></string>
<string name="gdpr_agree" translatable="false">Yes, I allow</string> <string name="gdpr_agree" translatable="false">Yes, I allow</string>
<string name="gdpr_disagree" translatable="false">No</string> <string name="gdpr_disagree" translatable="false">No</string>
<string name="empty" translatable="false" /> <string name="empty" translatable="false" />
</resources> </resources>

View File

@ -1,23 +1,23 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar"> <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="windowActionBar">false</item> <item name="windowActionBar">false</item>
<item name="android:windowBackground">@drawable/bg</item> <item name="android:windowBackground">@drawable/bg</item>
<item name="android:windowFullscreen">true</item> <item name="android:windowFullscreen">true</item>
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="p">shortEdges <item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="p">shortEdges
</item> </item>
<item name="android:fontFamily">@font/retron2000</item> <item name="android:fontFamily">@font/retron2000</item>
</style> </style>
<style name="RateMe" parent="Theme.AppCompat.Light.Dialog"> <style name="RateMe" parent="Theme.AppCompat.Light.Dialog">
<item name="colorControlActivated">#008c80</item> <item name="colorControlActivated">#008c80</item>
<item name="android:windowBackground">@drawable/custom_dialog_rounded</item> <item name="android:windowBackground">@drawable/custom_dialog_rounded</item>
</style> </style>
<style name="CustomProgressBar" parent="Widget.AppCompat.ProgressBar.Horizontal"> <style name="CustomProgressBar" parent="Widget.AppCompat.ProgressBar.Horizontal">
<item name="android:indeterminateOnly">false</item> <item name="android:indeterminateOnly">false</item>
<item name="android:progressDrawable">@drawable/custom_progress_bar</item> <item name="android:progressDrawable">@drawable/custom_progress_bar</item>
</style> </style>
</resources> </resources>

View File

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<full-backup-content> <full-backup-content>
<exclude <exclude
domain="sharedpref" domain="sharedpref"
path="MultiCraftSettings.xml" /> path="MultiCraftSettings.xml" />
<exclude <exclude
domain="sharedpref" domain="sharedpref"
path="RateMe.xml" /> path="RateMe.xml" />
<exclude <exclude
domain="sharedpref" domain="sharedpref"
path="com.multicraft.game_preferences.xml" /> path="com.multicraft.game_preferences.xml" />
</full-backup-content> </full-backup-content>

View File

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<network-security-config> <network-security-config>
<base-config cleartextTrafficPermitted="true"> <base-config cleartextTrafficPermitted="true">
<trust-anchors> <trust-anchors>
<certificates src="system" /> <certificates src="system" />
<certificates src="user" /> <certificates src="user" />
</trust-anchors> </trust-anchors>
</base-config> </base-config>
<domain-config cleartextTrafficPermitted="true"> <domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">127.0.0.1</domain> <domain includeSubdomains="true">127.0.0.1</domain>
</domain-config> </domain-config>
</network-security-config> </network-security-config>