From 1538e5bc9942839ac69f165367eeed61e5c1ea30 Mon Sep 17 00:00:00 2001 From: Bektur Date: Thu, 26 Oct 2023 21:25:16 +0600 Subject: [PATCH] Android: update Kotlin part (#150) --- Android/app/build.gradle | 11 +- Android/app/src/main/AndroidManifest.xml | 22 ++- .../com/multicraft/game/CustomEditText.kt | 4 +- .../java/com/multicraft/game/GameActivity.kt | 103 ++++++----- .../java/com/multicraft/game/MainActivity.kt | 171 ++++++++++-------- .../game/dialogs/ConnectionDialog.kt | 96 ++++++++++ .../multicraft/game/dialogs/RestartDialog.kt | 76 ++++++++ .../multicraft/game/helpers/ApiLevelHelper.kt | 6 +- .../game/helpers/PreferenceHelper.kt | 4 +- .../game/helpers/UsefulExtensions.kt | 113 +++--------- .../game/workmanager/UnzipWorker.kt | 7 +- .../game/workmanager/WorkerViewModel.kt | 4 +- .../workmanager/WorkerViewModelFactory.kt | 4 +- .../app/src/main/res/anim/slide_in_bottom.xml | 5 + .../app/src/main/res/anim/slide_in_top.xml | 5 + .../src/main/res/anim/slide_out_bottom.xml | 5 + .../app/src/main/res/anim/slide_out_top.xml | 5 + .../src/main/res/drawable-night/bg_input.xml | 3 + .../app/src/main/res/drawable/btn_green.xml | 5 + Android/app/src/main/res/drawable/btn_red.xml | 5 + .../app/src/main/res/drawable/btn_yellow.xml | 5 + .../main/res/drawable/custom_progress_bar.xml | 9 - Android/app/src/main/res/drawable/green.9.png | Bin 0 -> 383 bytes .../src/main/res/drawable/green_pressed.9.png | Bin 0 -> 383 bytes .../main/res/drawable/ic_baseline_send.xml | 4 +- Android/app/src/main/res/drawable/loading.xml | 28 +++ .../src/main/res/drawable/loading_anim1.png | Bin 0 -> 1028 bytes .../src/main/res/drawable/loading_anim2.png | Bin 0 -> 1025 bytes .../src/main/res/drawable/loading_anim3.png | Bin 0 -> 1024 bytes .../src/main/res/drawable/loading_anim4.png | Bin 0 -> 1021 bytes .../src/main/res/drawable/loading_anim5.png | Bin 0 -> 1023 bytes .../src/main/res/drawable/loading_anim6.png | Bin 0 -> 1015 bytes .../src/main/res/drawable/loading_anim7.png | Bin 0 -> 1016 bytes .../src/main/res/drawable/loading_anim8.png | Bin 0 -> 1021 bytes .../app/src/main/res/drawable/progress.xml | 5 - .../src/main/res/drawable/progress_bar.webp | Bin 218 -> 0 bytes .../main/res/drawable/progress_bar_bg.webp | Bin 226 -> 0 bytes .../src/main/res/drawable/progress_bar_fg.png | Bin 222 -> 0 bytes Android/app/src/main/res/drawable/red.9.png | Bin 0 -> 374 bytes .../src/main/res/drawable/red_pressed.9.png | Bin 0 -> 375 bytes .../app/src/main/res/drawable/yellow.9.png | Bin 0 -> 375 bytes .../main/res/drawable/yellow_pressed.9.png | Bin 0 -> 375 bytes .../app/src/main/res/layout/activity_main.xml | 40 ++-- .../app/src/main/res/layout/conn_dialog.xml | 61 ------- .../src/main/res/layout/connection_dialog.xml | 78 ++++++++ .../app/src/main/res/layout/input_text.xml | 7 +- .../src/main/res/layout/multiline_input.xml | 7 +- .../src/main/res/layout/restart_dialog.xml | 87 +++++---- Android/app/src/main/res/mipmap/ic_dialog.png | Bin 0 -> 4856 bytes .../app/src/main/res/values-ru/strings.xml | 6 +- .../app/src/main/res/values-sw600dp/attrs.xml | 3 - .../app/src/main/res/values-v26/styles.xml | 12 ++ .../app/src/main/res/values-v27/styles.xml | 13 ++ Android/app/src/main/res/values/attrs.xml | 3 - Android/app/src/main/res/values/colors.xml | 2 - Android/app/src/main/res/values/strings.xml | 5 +- Android/app/src/main/res/values/styles.xml | 25 +-- Android/native/build.gradle | 6 +- 58 files changed, 645 insertions(+), 415 deletions(-) create mode 100644 Android/app/src/main/java/com/multicraft/game/dialogs/ConnectionDialog.kt create mode 100644 Android/app/src/main/java/com/multicraft/game/dialogs/RestartDialog.kt create mode 100644 Android/app/src/main/res/anim/slide_in_bottom.xml create mode 100644 Android/app/src/main/res/anim/slide_in_top.xml create mode 100644 Android/app/src/main/res/anim/slide_out_bottom.xml create mode 100644 Android/app/src/main/res/anim/slide_out_top.xml create mode 100644 Android/app/src/main/res/drawable/btn_green.xml create mode 100644 Android/app/src/main/res/drawable/btn_red.xml create mode 100644 Android/app/src/main/res/drawable/btn_yellow.xml delete mode 100644 Android/app/src/main/res/drawable/custom_progress_bar.xml create mode 100644 Android/app/src/main/res/drawable/green.9.png create mode 100644 Android/app/src/main/res/drawable/green_pressed.9.png create mode 100644 Android/app/src/main/res/drawable/loading.xml create mode 100644 Android/app/src/main/res/drawable/loading_anim1.png create mode 100644 Android/app/src/main/res/drawable/loading_anim2.png create mode 100644 Android/app/src/main/res/drawable/loading_anim3.png create mode 100644 Android/app/src/main/res/drawable/loading_anim4.png create mode 100644 Android/app/src/main/res/drawable/loading_anim5.png create mode 100644 Android/app/src/main/res/drawable/loading_anim6.png create mode 100644 Android/app/src/main/res/drawable/loading_anim7.png create mode 100644 Android/app/src/main/res/drawable/loading_anim8.png delete mode 100644 Android/app/src/main/res/drawable/progress.xml delete mode 100644 Android/app/src/main/res/drawable/progress_bar.webp delete mode 100644 Android/app/src/main/res/drawable/progress_bar_bg.webp delete mode 100644 Android/app/src/main/res/drawable/progress_bar_fg.png create mode 100644 Android/app/src/main/res/drawable/red.9.png create mode 100644 Android/app/src/main/res/drawable/red_pressed.9.png create mode 100644 Android/app/src/main/res/drawable/yellow.9.png create mode 100644 Android/app/src/main/res/drawable/yellow_pressed.9.png delete mode 100644 Android/app/src/main/res/layout/conn_dialog.xml create mode 100644 Android/app/src/main/res/layout/connection_dialog.xml create mode 100644 Android/app/src/main/res/mipmap/ic_dialog.png delete mode 100644 Android/app/src/main/res/values-sw600dp/attrs.xml create mode 100644 Android/app/src/main/res/values-v26/styles.xml create mode 100644 Android/app/src/main/res/values-v27/styles.xml delete mode 100644 Android/app/src/main/res/values/attrs.xml diff --git a/Android/app/build.gradle b/Android/app/build.gradle index d33816d36..a977d0ee9 100644 --- a/Android/app/build.gradle +++ b/Android/app/build.gradle @@ -2,13 +2,13 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' android { - compileSdkVersion 33 - buildToolsVersion '33.0.2' + compileSdkVersion 34 + buildToolsVersion '34.0.0' ndkVersion '25.2.9519653' defaultConfig { applicationId 'com.multicraft.game' minSdkVersion 21 - targetSdkVersion 33 + targetSdkVersion 34 versionName "${versionMajor}.${versionMinor}.${versionPatch}" versionCode project.versionCode } @@ -100,7 +100,7 @@ tasks.register('prepareAssetsFiles') { tasks.register('zipAssetsFiles', Zip) { dependsOn prepareAssetsFiles archiveFileName = 'assets.zip' - destinationDirectory = file('src/main/assets/data') + destinationDirectory = file('src/main/assets') from('build/assets/Files') } @@ -125,7 +125,8 @@ dependencies { /* Third-party libraries */ implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.appcompat:appcompat-resources:1.6.1' + implementation("androidx.browser:browser:1.6.0") implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2' implementation 'androidx.work:work-runtime-ktx:2.8.1' - implementation 'com.google.android.material:material:1.9.0' + implementation 'com.google.android.material:material:1.10.0' } diff --git a/Android/app/src/main/AndroidManifest.xml b/Android/app/src/main/AndroidManifest.xml index 7e743f503..028143246 100644 --- a/Android/app/src/main/AndroidManifest.xml +++ b/Android/app/src/main/AndroidManifest.xml @@ -28,7 +28,6 @@ + + + diff --git a/Android/app/src/main/java/com/multicraft/game/CustomEditText.kt b/Android/app/src/main/java/com/multicraft/game/CustomEditText.kt index c924a63c8..baf240b64 100644 --- a/Android/app/src/main/java/com/multicraft/game/CustomEditText.kt +++ b/Android/app/src/main/java/com/multicraft/game/CustomEditText.kt @@ -1,7 +1,7 @@ /* MultiCraft -Copyright (C) 2014-2022 MoNTE48, Maksim Gamarnik -Copyright (C) 2014-2022 ubulem, Bektur Mambetov +Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2023 ubulem, Bektur Mambetov This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by diff --git a/Android/app/src/main/java/com/multicraft/game/GameActivity.kt b/Android/app/src/main/java/com/multicraft/game/GameActivity.kt index 371783a38..1118fcce3 100644 --- a/Android/app/src/main/java/com/multicraft/game/GameActivity.kt +++ b/Android/app/src/main/java/com/multicraft/game/GameActivity.kt @@ -1,7 +1,7 @@ /* MultiCraft -Copyright (C) 2014-2022 MoNTE48, Maksim Gamarnik -Copyright (C) 2014-2022 ubulem, Bektur Mambetov +Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2023 ubulem, Bektur Mambetov This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -20,11 +20,9 @@ with this program; if not, write to the Free Software Foundation, Inc., package com.multicraft.game -import android.content.Intent import android.content.res.Configuration -import android.content.res.Configuration.HARDKEYBOARDHIDDEN_NO import android.net.Uri -import android.os.Bundle +import android.os.* import android.text.InputType import android.view.* import android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN @@ -33,12 +31,15 @@ import android.view.inputmethod.EditorInfo import android.view.inputmethod.InputMethodManager import android.widget.TextView import androidx.appcompat.app.AlertDialog +import androidx.browser.customtabs.CustomTabsIntent +import androidx.browser.customtabs.CustomTabsIntent.SHARE_STATE_OFF import com.multicraft.game.MainActivity.Companion.radius -import com.multicraft.game.databinding.InputTextBinding -import com.multicraft.game.databinding.MultilineInputBinding +import com.multicraft.game.databinding.* import com.multicraft.game.helpers.* import com.multicraft.game.helpers.ApiLevelHelper.isOreo import org.libsdl.app.SDLActivity +import java.util.* +import kotlin.system.exitProcess class GameActivity : SDLActivity() { companion object { @@ -54,21 +55,21 @@ class GameActivity : SDLActivity() { private var messageReturnValue = "" private var hasKeyboard = false + override fun getLibraries() = arrayOf("MultiCraft") - override fun getLibraries(): Array { - return arrayOf( - "MultiCraft" - ) - } - - override fun getMainSharedObject(): String { - return getContext().applicationInfo.nativeLibraryDir + "/libMultiCraft.so" - } + override fun getMainSharedObject() = + "${getContext().applicationInfo.nativeLibraryDir}/libMultiCraft.so" override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) + try { + super.onCreate(savedInstanceState) + } catch (e: Error) { + exitProcess(0) + } catch (e: Exception) { + exitProcess(0) + } window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) - hasKeyboard = resources.configuration.hardKeyboardHidden == HARDKEYBOARDHIDDEN_NO + hasKeyboard = hasHardKeyboard() } override fun onWindowFocusChanged(hasFocus: Boolean) { @@ -88,15 +89,13 @@ class GameActivity : SDLActivity() { override fun onResume() { super.onResume() - if (hasKeyboard) - keyboardEvent(hasKeyboard) + if (hasKeyboard) keyboardEvent(true) window.makeFullScreen() } override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) - val statusKeyboard = - resources.configuration.hardKeyboardHidden == HARDKEYBOARDHIDDEN_NO + val statusKeyboard = hasHardKeyboard() if (hasKeyboard != statusKeyboard) { hasKeyboard = statusKeyboard keyboardEvent(hasKeyboard) @@ -137,8 +136,8 @@ class GameActivity : SDLActivity() { editText.inputType = inputType editText.setSelection(editText.text?.length ?: 0) // for Android OS - editText.setOnEditorActionListener { _: TextView?, KeyCode: Int, _: KeyEvent? -> - if (KeyCode == KeyEvent.KEYCODE_ENTER || KeyCode == KeyEvent.KEYCODE_ENDCALL) { + editText.setOnEditorActionListener { _: TextView?, keyCode: Int, _: KeyEvent? -> + if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_ENDCALL) { imm.hideSoftInputFromWindow(editText.windowToken, 0) messageReturnValue = editText.text.toString() alertDialog.dismiss() @@ -147,16 +146,17 @@ class GameActivity : SDLActivity() { } return@setOnEditorActionListener false } - // for Chrome OS - editText.setOnKeyListener { _: View?, KeyCode: Int, _: KeyEvent? -> - if (KeyCode == KeyEvent.KEYCODE_ENTER || KeyCode == KeyEvent.KEYCODE_ENDCALL) { - imm.hideSoftInputFromWindow(editText.windowToken, 0) - messageReturnValue = editText.text.toString() - alertDialog.dismiss() - isInputActive = false - return@setOnKeyListener true + if (isChromebook()) { + editText.setOnKeyListener { _: View?, keyCode: Int, _: KeyEvent? -> + if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_ENDCALL) { + imm.hideSoftInputFromWindow(editText.windowToken, 0) + messageReturnValue = editText.text.toString() + alertDialog.dismiss() + isInputActive = false + return@setOnKeyListener true + } + return@setOnKeyListener false } - return@setOnKeyListener false } binding.input.setEndIconOnClickListener { imm.hideSoftInputFromWindow(editText.windowToken, 0) @@ -174,7 +174,7 @@ class GameActivity : SDLActivity() { // should be above `show()` alertWindow.setSoftInputMode(SOFT_INPUT_STATE_VISIBLE) alertDialog.show() - if (!resources.getBoolean(R.bool.isTablet)) + if (!isTablet()) alertWindow.makeFullScreenAlert() alertDialog.setOnCancelListener { window.setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_HIDDEN) @@ -200,8 +200,8 @@ class GameActivity : SDLActivity() { editText.setSelection(editText.text?.length ?: 0) val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager // for Android OS - editText.setOnEditorActionListener { _: TextView?, KeyCode: Int, _: KeyEvent? -> - if (KeyCode == KeyEvent.KEYCODE_ENTER || KeyCode == KeyEvent.KEYCODE_ENDCALL) { + editText.setOnEditorActionListener { _: TextView?, keyCode: Int, _: KeyEvent? -> + if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_ENDCALL) { imm.hideSoftInputFromWindow(editText.windowToken, 0) messageReturnValue = editText.text.toString() alertDialog.dismiss() @@ -210,16 +210,17 @@ class GameActivity : SDLActivity() { } return@setOnEditorActionListener false } - // for Chrome OS - editText.setOnKeyListener { _: View?, KeyCode: Int, _: KeyEvent? -> - if (KeyCode == KeyEvent.KEYCODE_ENTER || KeyCode == KeyEvent.KEYCODE_ENDCALL) { - imm.hideSoftInputFromWindow(editText.windowToken, 0) - messageReturnValue = editText.text.toString() - alertDialog.dismiss() - isInputActive = false - return@setOnKeyListener true + if (isChromebook()) { + editText.setOnKeyListener { _: View?, keyCode: Int, _: KeyEvent? -> + if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_ENDCALL) { + imm.hideSoftInputFromWindow(editText.windowToken, 0) + messageReturnValue = editText.text.toString() + alertDialog.dismiss() + isInputActive = false + return@setOnKeyListener true + } + return@setOnKeyListener false } - return@setOnKeyListener false } binding.multiInput.setEndIconOnClickListener { imm.hideSoftInputFromWindow(editText.windowToken, 0) @@ -237,7 +238,7 @@ class GameActivity : SDLActivity() { val alertWindow = alertDialog.window!! alertWindow.setSoftInputMode(SOFT_INPUT_STATE_VISIBLE) alertDialog.show() - if (!resources.getBoolean(R.bool.isTablet)) + if (!isTablet()) alertWindow.makeFullScreenAlert() alertDialog.setOnCancelListener { window.setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_HIDDEN) @@ -270,9 +271,13 @@ class GameActivity : SDLActivity() { @Suppress("unused") fun openURI(uri: String?) { + val builder = CustomTabsIntent.Builder() + builder.setShareState(SHARE_STATE_OFF) + .setStartAnimations(this, R.anim.slide_in_bottom, R.anim.slide_out_top) + .setExitAnimations(this, R.anim.slide_in_top, R.anim.slide_out_bottom) + val customTabsIntent = builder.build() try { - val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(uri)) - startActivity(browserIntent) + customTabsIntent.launchUrl(this, Uri.parse(uri)) } catch (ignored: Exception) { } } @@ -292,7 +297,7 @@ class GameActivity : SDLActivity() { @Suppress("unused") fun getSecretKey(key: String): String { - return "Stub" + return key } @Suppress("unused") diff --git a/Android/app/src/main/java/com/multicraft/game/MainActivity.kt b/Android/app/src/main/java/com/multicraft/game/MainActivity.kt index 3845ddb14..419d54fa1 100644 --- a/Android/app/src/main/java/com/multicraft/game/MainActivity.kt +++ b/Android/app/src/main/java/com/multicraft/game/MainActivity.kt @@ -1,7 +1,7 @@ /* MultiCraft -Copyright (C) 2014-2022 MoNTE48, Maksim Gamarnik -Copyright (C) 2014-2022 ubulem, Bektur Mambetov +Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2023 ubulem, Bektur Mambetov This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -22,18 +22,25 @@ package com.multicraft.game import android.content.Intent import android.content.SharedPreferences -import android.graphics.Color -import android.graphics.drawable.LayerDrawable +import android.graphics.drawable.AnimationDrawable import android.os.Bundle -import android.view.* +import android.provider.Settings.ACTION_WIFI_SETTINGS +import android.provider.Settings.ACTION_WIRELESS_SETTINGS +import android.view.RoundedCorner +import android.view.WindowManager +import androidx.activity.OnBackPressedCallback +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity -import androidx.core.graphics.BlendModeColorFilterCompat -import androidx.core.graphics.BlendModeCompat -import androidx.lifecycle.* +import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import androidx.work.WorkInfo import com.multicraft.game.databinding.ActivityMainBinding +import com.multicraft.game.dialogs.ConnectionDialog import com.multicraft.game.helpers.* import com.multicraft.game.helpers.ApiLevelHelper.isAndroid12 +import com.multicraft.game.helpers.ApiLevelHelper.isPie import com.multicraft.game.helpers.PreferenceHelper.TAG_BUILD_VER import com.multicraft.game.helpers.PreferenceHelper.getStringValue import com.multicraft.game.helpers.PreferenceHelper.set @@ -49,11 +56,14 @@ class MainActivity : AppCompatActivity() { private var externalStorage: File? = null private val sep = File.separator private lateinit var prefs: SharedPreferences + private lateinit var restartStartForResult: ActivityResultLauncher + private lateinit var connStartForResult: ActivityResultLauncher private val versionCode = BuildConfig.VERSION_CODE private val versionName = "${BuildConfig.VERSION_NAME}+$versionCode" companion object { var radius = 0 + const val NO_SPACE_LEFT = "ENOSPC" } override fun onCreate(savedInstanceState: Bundle?) { @@ -61,30 +71,34 @@ class MainActivity : AppCompatActivity() { window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) + onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + } + }) + connStartForResult = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { + checkAppVersion() + } + restartStartForResult = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { + if (it.resultCode == RESULT_OK) + finishApp(true) + else + finishApp(false) + } try { prefs = PreferenceHelper.init(this) externalStorage = getExternalFilesDir(null) - if (filesDir == null || cacheDir == null || externalStorage == null) - throw IOException("Bad disk space state") + listOf(filesDir, cacheDir, externalStorage).requireNoNulls() checkConnection() - } catch (e: Exception) { // Storage -> IOException, Prefs -> GeneralSecurityException - showRestartDialog(!e.message!!.contains("ENOPSC")) + } catch (e: Exception) { + val isRestart = e.message?.contains(NO_SPACE_LEFT) != true + showRestartDialog(restartStartForResult, isRestart) } } - @Deprecated("Deprecated in Java") - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - @Suppress("DEPRECATION") - super.onActivityResult(requestCode, resultCode, data) - if (requestCode == 104) - checkAppVersion() - } - - @Deprecated("Deprecated in Java") - override fun onBackPressed() { - // Prevent abrupt interruption when copy game files from assets - } - override fun onResume() { super.onResume() window.makeFullScreen() @@ -97,81 +111,66 @@ class MainActivity : AppCompatActivity() { override fun onAttachedToWindow() { super.onAttachedToWindow() - if (isAndroid12()) { - val insets = window.decorView.rootWindowInsets - if (insets != null) { - val tl = insets.getRoundedCorner(RoundedCorner.POSITION_TOP_LEFT) - radius = tl?.radius ?: 0 + if (isPie()) { + val cutout = window.decorView.rootWindowInsets.displayCutout + if (cutout != null) { + radius = 40 + } + if (isAndroid12()) { + val insets = window.decorView.rootWindowInsets + if (insets != null) { + val tl = insets.getRoundedCorner(RoundedCorner.POSITION_TOP_LEFT) + radius = tl?.radius ?: if (cutout != null) 40 else 0 + } } } - } - - - // interface - private fun showProgress(textMessage: Int, progress: Int) { - if (binding.progressBar.visibility == View.GONE) { - binding.tvProgress.setText(textMessage) - binding.progressCircle.visibility = View.GONE - binding.progressBar.visibility = View.VISIBLE - binding.progressBar.progress = 0 - } else if (progress > 0) { - val progressMessage = "${getString(textMessage)} $progress%" - binding.tvProgress.text = progressMessage - binding.progressBar.progress = progress - // colorize the progress bar - val progressBarDrawable = - (binding.progressBar.progressDrawable as LayerDrawable).getDrawable(0) - val progressDrawable = (progressBarDrawable as LayerDrawable).getDrawable(1) - val color = Color.rgb(255 - progress * 2, progress * 2, 25) - progressDrawable.colorFilter = - BlendModeColorFilterCompat.createBlendModeColorFilterCompat( - color, BlendModeCompat.SRC_IN - ) - } + val animation = binding.loadingAnim.drawable as AnimationDrawable + animation.start() } private fun startNative() { val initLua = File(filesDir, "builtin${sep}mainmenu${sep}init.lua") if (initLua.exists() && initLua.canRead()) { val intent = Intent(this, GameActivity::class.java) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) startActivity(intent) } else { prefs[TAG_BUILD_VER] = "0" - showRestartDialog() + showRestartDialog(restartStartForResult) } } private fun prepareToRun() { - binding.tvProgress.setText(R.string.preparing) - binding.progressCircle.visibility = View.VISIBLE - binding.progressBar.visibility = View.GONE - val filesList = listOf( - File(externalStorage, "debug.txt"), - File(filesDir, "builtin"), - File(filesDir, "client"), - File(filesDir, "fonts"), - File(filesDir, "textures") - ) - val zips = assets.list("data")!!.toList() + val filesList = mutableListOf().apply { + addAll(listOf( + "builtin", + "client${sep}shaders", + "fonts", + "games${sep}default", + "textures${sep}base" + ).map { File(filesDir, it) }) + } + + val zips = mutableListOf("assets.zip") + lifecycleScope.launch { filesList.forEach { it.deleteRecursively() } zips.forEach { try { - assets.open("data$sep$it").use { input -> + assets.open(it).use { input -> File(cacheDir, it).copyInputStreamToFile(input) } } catch (e: IOException) { - runOnUiThread { showRestartDialog(!e.message!!.contains("ENOSPC")) } + val isNotEnoughSpace = e.message!!.contains(NO_SPACE_LEFT) + runOnUiThread { showRestartDialog(restartStartForResult, !isNotEnoughSpace) } return@forEach } } try { - startUnzipWorker(zips) + startUnzipWorker(zips.toTypedArray()) } catch (e: Exception) { - runOnUiThread { showRestartDialog() } + runOnUiThread { showRestartDialog(restartStartForResult) } } } } @@ -184,31 +183,47 @@ class MainActivity : AppCompatActivity() { prepareToRun() } + private fun showConnectionDialog() { + val intent = Intent(this, ConnectionDialog::class.java) + val startForResult = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { + when (it.resultCode) { + RESULT_OK -> connStartForResult.launch(Intent(ACTION_WIFI_SETTINGS)) + RESULT_FIRST_USER -> connStartForResult.launch(Intent(ACTION_WIRELESS_SETTINGS)) + else -> checkAppVersion() + } + } + startForResult.launch(intent) + } + // check connection available private fun checkConnection() = lifecycleScope.launch { - val result = isConnected() - if (result) checkAppVersion() + if (isConnected()) checkAppVersion() else try { - showConnectionDialog { checkAppVersion() } + showConnectionDialog() } catch (e: Exception) { checkAppVersion() } } - private fun startUnzipWorker(file: List) { - val viewModelFactory = WorkerViewModelFactory(application, file.toTypedArray()) + private fun startUnzipWorker(file: Array) { + val viewModelFactory = WorkerViewModelFactory(application, file) val viewModel = ViewModelProvider(this, viewModelFactory)[WorkerViewModel::class.java] viewModel.unzippingWorkObserver .observe(this, Observer { workInfo -> if (workInfo == null) return@Observer val progress = workInfo.progress.getInt(PROGRESS, 0) - showProgress(R.string.loading, progress) + if (progress > 0) { + val progressMessage = "${getString(R.string.loading)} $progress%" + binding.tvProgress.text = progressMessage + } if (workInfo.state.isFinished) { if (workInfo.state == WorkInfo.State.FAILED) { val isRestart = workInfo.outputData.getBoolean("restart", true) - showRestartDialog(isRestart) + showRestartDialog(restartStartForResult, isRestart) } else if (workInfo.state == WorkInfo.State.SUCCEEDED) { prefs[TAG_BUILD_VER] = versionName startNative() diff --git a/Android/app/src/main/java/com/multicraft/game/dialogs/ConnectionDialog.kt b/Android/app/src/main/java/com/multicraft/game/dialogs/ConnectionDialog.kt new file mode 100644 index 000000000..35bd8257b --- /dev/null +++ b/Android/app/src/main/java/com/multicraft/game/dialogs/ConnectionDialog.kt @@ -0,0 +1,96 @@ +/* +MultiCraft +Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2023 ubulem, Bektur Mambetov + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3.0 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +package com.multicraft.game.dialogs + +import android.app.Activity +import android.content.Context +import android.content.res.Configuration +import android.os.Bundle +import android.telephony.TelephonyManager +import android.telephony.TelephonyManager.SIM_STATE_READY +import android.view.View +import android.widget.LinearLayout +import androidx.activity.OnBackPressedCallback +import androidx.appcompat.app.AppCompatActivity +import com.multicraft.game.databinding.ConnectionDialogBinding +import com.multicraft.game.helpers.ApiLevelHelper.isOreo +import com.multicraft.game.helpers.makeFullScreen +import org.libsdl.app.SDLActivity + +class ConnectionDialog : AppCompatActivity() { + private fun isSimCardPresent(): Boolean { + val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager + + if (!isOreo()) + return telephonyManager.simState == SIM_STATE_READY + + val isFirstSimPresent = telephonyManager.getSimState(0) == SIM_STATE_READY + val isSecondSimPresent = telephonyManager.getSimState(1) == SIM_STATE_READY + + return isFirstSimPresent || isSecondSimPresent + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val binding = ConnectionDialogBinding.inflate(layoutInflater) + if (SDLActivity.isTablet()) { + val param = LinearLayout.LayoutParams( + 0, + LinearLayout.LayoutParams.WRAP_CONTENT, + 0.5f + ) + binding.connRoot.layoutParams = param + } + if (isSimCardPresent()) + binding.mobile.visibility = View.VISIBLE + setContentView(binding.root) + + onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + } + }) + + binding.wifi.setOnClickListener { + setResult(Activity.RESULT_OK) + finish() + } + binding.mobile.setOnClickListener { + setResult(Activity.RESULT_FIRST_USER) + finish() + } + binding.ignore.setOnClickListener { + setResult(Activity.RESULT_CANCELED) + finish() + } + } + + override fun onResume() { + super.onResume() + window.makeFullScreen() + } + + override fun attachBaseContext(base: Context?) { + val configuration = Configuration(base?.resources?.configuration) + configuration.fontScale = 1.0f + applyOverrideConfiguration(configuration) + super.attachBaseContext(base) + } +} diff --git a/Android/app/src/main/java/com/multicraft/game/dialogs/RestartDialog.kt b/Android/app/src/main/java/com/multicraft/game/dialogs/RestartDialog.kt new file mode 100644 index 000000000..733fd6a74 --- /dev/null +++ b/Android/app/src/main/java/com/multicraft/game/dialogs/RestartDialog.kt @@ -0,0 +1,76 @@ +/* +MultiCraft +Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2023 ubulem, Bektur Mambetov + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3.0 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +package com.multicraft.game.dialogs + +import android.app.Activity +import android.content.Context +import android.content.res.Configuration +import android.os.Bundle +import android.widget.LinearLayout +import androidx.activity.OnBackPressedCallback +import androidx.appcompat.app.AppCompatActivity +import com.multicraft.game.databinding.RestartDialogBinding +import com.multicraft.game.helpers.makeFullScreen +import org.libsdl.app.SDLActivity + +class RestartDialog : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val binding = RestartDialogBinding.inflate(layoutInflater) + if (SDLActivity.isTablet()) { + val param = LinearLayout.LayoutParams( + 0, + LinearLayout.LayoutParams.WRAP_CONTENT, + 0.5f + ) + binding.restartRoot.layoutParams = param + } + setContentView(binding.root) + + onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + } + }) + + val message = intent.getStringExtra("message")!! + binding.errorDesc.text = message + binding.restart.setOnClickListener { + setResult(Activity.RESULT_OK) + finish() + } + binding.close.setOnClickListener { + setResult(Activity.RESULT_CANCELED) + finish() + } + } + + override fun onResume() { + super.onResume() + window.makeFullScreen() + } + + override fun attachBaseContext(base: Context?) { + val configuration = Configuration(base?.resources?.configuration) + configuration.fontScale = 1.0f + applyOverrideConfiguration(configuration) + super.attachBaseContext(base) + } +} diff --git a/Android/app/src/main/java/com/multicraft/game/helpers/ApiLevelHelper.kt b/Android/app/src/main/java/com/multicraft/game/helpers/ApiLevelHelper.kt index 10110b846..380760dd7 100644 --- a/Android/app/src/main/java/com/multicraft/game/helpers/ApiLevelHelper.kt +++ b/Android/app/src/main/java/com/multicraft/game/helpers/ApiLevelHelper.kt @@ -1,7 +1,7 @@ /* MultiCraft -Copyright (C) 2014-2022 MoNTE48, Maksim Gamarnik -Copyright (C) 2014-2022 ubulem, Bektur Mambetov +Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2023 ubulem, Bektur Mambetov This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -30,5 +30,7 @@ object ApiLevelHelper { fun isOreo() = isGreaterOrEqual(O) + fun isPie() = isGreaterOrEqual(P) + fun isAndroid12() = isGreaterOrEqual(S) } diff --git a/Android/app/src/main/java/com/multicraft/game/helpers/PreferenceHelper.kt b/Android/app/src/main/java/com/multicraft/game/helpers/PreferenceHelper.kt index 8080789af..11626b39f 100644 --- a/Android/app/src/main/java/com/multicraft/game/helpers/PreferenceHelper.kt +++ b/Android/app/src/main/java/com/multicraft/game/helpers/PreferenceHelper.kt @@ -1,7 +1,7 @@ /* MultiCraft -Copyright (C) 2014-2022 MoNTE48, Maksim Gamarnik -Copyright (C) 2014-2022 ubulem, Bektur Mambetov +Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2023 ubulem, Bektur Mambetov This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by diff --git a/Android/app/src/main/java/com/multicraft/game/helpers/UsefulExtensions.kt b/Android/app/src/main/java/com/multicraft/game/helpers/UsefulExtensions.kt index 966541f2b..a4f0a79aa 100644 --- a/Android/app/src/main/java/com/multicraft/game/helpers/UsefulExtensions.kt +++ b/Android/app/src/main/java/com/multicraft/game/helpers/UsefulExtensions.kt @@ -1,7 +1,7 @@ /* MultiCraft -Copyright (C) 2014-2022 MoNTE48, Maksim Gamarnik -Copyright (C) 2014-2022 ubulem, Bektur Mambetov +Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2023 ubulem, Bektur Mambetov This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -23,31 +23,22 @@ package com.multicraft.game.helpers import android.app.* import android.content.Context import android.content.Intent -import android.content.pm.PackageManager -import android.net.ConnectivityManager -import android.net.NetworkCapabilities -import android.provider.Settings -import android.view.View +import android.content.res.Configuration +import android.net.* +import android.os.* import android.view.Window -import androidx.appcompat.app.AlertDialog +import androidx.activity.result.ActivityResultLauncher import androidx.appcompat.app.AppCompatActivity -import androidx.core.content.ContextCompat import androidx.core.view.* -import com.multicraft.game.R -import com.multicraft.game.databinding.ConnDialogBinding -import com.multicraft.game.databinding.RestartDialogBinding +import com.multicraft.game.* +import com.multicraft.game.databinding.* +import com.multicraft.game.dialogs.RestartDialog import com.multicraft.game.helpers.ApiLevelHelper.isAndroid12 -import java.io.File -import java.io.InputStream -import kotlin.system.exitProcess +import com.multicraft.game.helpers.ApiLevelHelper.isMarshmallow +import java.io.* +import java.util.* // Activity extensions -fun AppCompatActivity.getIcon() = try { - packageManager.getApplicationIcon(packageName) -} catch (e: PackageManager.NameNotFoundException) { - ContextCompat.getDrawable(this, R.mipmap.ic_launcher) -} - fun Activity.finishApp(restart: Boolean) { if (restart) { val intent = Intent(this, this::class.java) @@ -61,72 +52,12 @@ fun Activity.finishApp(restart: Boolean) { ) ) } - exitProcess(0) + finish() } -fun AppCompatActivity.defaultDialog(title: Int, view: View, style: Int = R.style.CustomDialog): AlertDialog { - val builder = AlertDialog.Builder(this, style) - .setIcon(getIcon()) - .setTitle(title) - .setCancelable(false) - .setView(view) - return builder.create() -} - -fun AppCompatActivity.headlessDialog( - view: View, - style: Int = R.style.LightTheme, - isCancelable: Boolean = false -): AlertDialog { - val builder = AlertDialog.Builder(this, style) - .setCancelable(isCancelable) - .setView(view) - return builder.create() -} - -fun AppCompatActivity.show(dialog: AlertDialog) { - window?.makeFullScreen() - if (!isFinishing) dialog.show() -} - -fun AppCompatActivity.showConnectionDialog(listener: (() -> Unit)? = null) { - val binding = ConnDialogBinding.inflate(layoutInflater) - val dialog = defaultDialog(R.string.conn_title, binding.root) - binding.wifi.setOnClickListener { - dialog.dismiss() - startActivityForResult( - Intent(Settings.ACTION_WIFI_SETTINGS), - 104 - ) - } - binding.mobile.setOnClickListener { - dialog.dismiss() - startActivityForResult( - Intent(Settings.ACTION_WIRELESS_SETTINGS), - 104 - ) - } - binding.ignore.setOnClickListener { - dialog.dismiss() - listener?.invoke() - } - show(dialog) -} - -fun AppCompatActivity.showRestartDialog(isRestart: Boolean = true) { - val message = - if (isRestart) getString(R.string.restart) else getString(R.string.no_space) - val binding = RestartDialogBinding.inflate(layoutInflater) - val dialog = headlessDialog(binding.root, R.style.CustomDialog) - binding.errorDesc.text = message - binding.close.setOnClickListener { finishApp(false) } - binding.restart.setOnClickListener { finishApp(true) } - show(dialog) -} - -fun AppCompatActivity.isConnected(): Boolean { +fun Activity.isConnected(): Boolean { val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager - if (ApiLevelHelper.isMarshmallow()) { + if (isMarshmallow()) { val activeNetwork = cm.activeNetwork ?: return false val capabilities = cm.getNetworkCapabilities(activeNetwork) ?: return false return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) @@ -136,6 +67,20 @@ fun AppCompatActivity.isConnected(): Boolean { } } +fun AppCompatActivity.showRestartDialog( + startForResult: ActivityResultLauncher, + isRestart: Boolean = true +) { + val message = + if (isRestart) getString(R.string.restart) else getString(R.string.no_space) + val intent = Intent(this, RestartDialog::class.java) + intent.putExtra("message", message) + startForResult.launch(intent) +} + +fun Activity.hasHardKeyboard() = + resources.configuration.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO + // Other extensions fun File.copyInputStreamToFile(inputStream: InputStream) = outputStream().use { fileOut -> inputStream.copyTo(fileOut, 8192) } diff --git a/Android/app/src/main/java/com/multicraft/game/workmanager/UnzipWorker.kt b/Android/app/src/main/java/com/multicraft/game/workmanager/UnzipWorker.kt index b9d71100a..6fe878965 100644 --- a/Android/app/src/main/java/com/multicraft/game/workmanager/UnzipWorker.kt +++ b/Android/app/src/main/java/com/multicraft/game/workmanager/UnzipWorker.kt @@ -1,7 +1,7 @@ /* MultiCraft -Copyright (C) 2014-2022 MoNTE48, Maksim Gamarnik -Copyright (C) 2014-2022 ubulem, Bektur Mambetov +Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2023 ubulem, Bektur Mambetov This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -26,6 +26,7 @@ import android.content.Context import android.content.Context.NOTIFICATION_SERVICE import androidx.core.app.NotificationCompat import androidx.work.* +import com.multicraft.game.MainActivity.Companion.NO_SPACE_LEFT import com.multicraft.game.R import com.multicraft.game.helpers.ApiLevelHelper.isOreo import com.multicraft.game.helpers.copyInputStreamToFile @@ -83,7 +84,7 @@ class UnzipWorker(private val appContext: Context, workerParams: WorkerParameter } Result.success() } catch (e: IOException) { - val isNotEnoughSpace = e.localizedMessage!!.contains("ENOSPC") + val isNotEnoughSpace = e.localizedMessage!!.contains(NO_SPACE_LEFT) val out = Data.Builder() .putBoolean("restart", !isNotEnoughSpace) .build() diff --git a/Android/app/src/main/java/com/multicraft/game/workmanager/WorkerViewModel.kt b/Android/app/src/main/java/com/multicraft/game/workmanager/WorkerViewModel.kt index 2601e56fb..1362df6ff 100644 --- a/Android/app/src/main/java/com/multicraft/game/workmanager/WorkerViewModel.kt +++ b/Android/app/src/main/java/com/multicraft/game/workmanager/WorkerViewModel.kt @@ -1,7 +1,7 @@ /* MultiCraft -Copyright (C) 2014-2022 MoNTE48, Maksim Gamarnik -Copyright (C) 2014-2022 ubulem, Bektur Mambetov +Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2023 ubulem, Bektur Mambetov This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by diff --git a/Android/app/src/main/java/com/multicraft/game/workmanager/WorkerViewModelFactory.kt b/Android/app/src/main/java/com/multicraft/game/workmanager/WorkerViewModelFactory.kt index d47d44182..861c4076e 100644 --- a/Android/app/src/main/java/com/multicraft/game/workmanager/WorkerViewModelFactory.kt +++ b/Android/app/src/main/java/com/multicraft/game/workmanager/WorkerViewModelFactory.kt @@ -1,7 +1,7 @@ /* MultiCraft -Copyright (C) 2014-2022 MoNTE48, Maksim Gamarnik -Copyright (C) 2014-2022 ubulem, Bektur Mambetov +Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2023 ubulem, Bektur Mambetov This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by diff --git a/Android/app/src/main/res/anim/slide_in_bottom.xml b/Android/app/src/main/res/anim/slide_in_bottom.xml new file mode 100644 index 000000000..7d71ec0dc --- /dev/null +++ b/Android/app/src/main/res/anim/slide_in_bottom.xml @@ -0,0 +1,5 @@ + + diff --git a/Android/app/src/main/res/anim/slide_in_top.xml b/Android/app/src/main/res/anim/slide_in_top.xml new file mode 100644 index 000000000..2590b13cb --- /dev/null +++ b/Android/app/src/main/res/anim/slide_in_top.xml @@ -0,0 +1,5 @@ + + diff --git a/Android/app/src/main/res/anim/slide_out_bottom.xml b/Android/app/src/main/res/anim/slide_out_bottom.xml new file mode 100644 index 000000000..ee271ddfd --- /dev/null +++ b/Android/app/src/main/res/anim/slide_out_bottom.xml @@ -0,0 +1,5 @@ + + diff --git a/Android/app/src/main/res/anim/slide_out_top.xml b/Android/app/src/main/res/anim/slide_out_top.xml new file mode 100644 index 000000000..139262fe4 --- /dev/null +++ b/Android/app/src/main/res/anim/slide_out_top.xml @@ -0,0 +1,5 @@ + + diff --git a/Android/app/src/main/res/drawable-night/bg_input.xml b/Android/app/src/main/res/drawable-night/bg_input.xml index afda4958d..1a72c7e0b 100644 --- a/Android/app/src/main/res/drawable-night/bg_input.xml +++ b/Android/app/src/main/res/drawable-night/bg_input.xml @@ -2,4 +2,7 @@ + diff --git a/Android/app/src/main/res/drawable/btn_green.xml b/Android/app/src/main/res/drawable/btn_green.xml new file mode 100644 index 000000000..da8f7ac66 --- /dev/null +++ b/Android/app/src/main/res/drawable/btn_green.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/Android/app/src/main/res/drawable/btn_red.xml b/Android/app/src/main/res/drawable/btn_red.xml new file mode 100644 index 000000000..d617af9a2 --- /dev/null +++ b/Android/app/src/main/res/drawable/btn_red.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/Android/app/src/main/res/drawable/btn_yellow.xml b/Android/app/src/main/res/drawable/btn_yellow.xml new file mode 100644 index 000000000..20509a2f6 --- /dev/null +++ b/Android/app/src/main/res/drawable/btn_yellow.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/Android/app/src/main/res/drawable/custom_progress_bar.xml b/Android/app/src/main/res/drawable/custom_progress_bar.xml deleted file mode 100644 index 932804b67..000000000 --- a/Android/app/src/main/res/drawable/custom_progress_bar.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - diff --git a/Android/app/src/main/res/drawable/green.9.png b/Android/app/src/main/res/drawable/green.9.png new file mode 100644 index 0000000000000000000000000000000000000000..98c1806026f7fc2931b2a142cc05bebc07aa866f GIT binary patch literal 383 zcmV-_0f7FAP)*gTY1Rj5$c&Cqfw{D^=H!Cj4uy@W9ymm!j_F~$f$ z48mH|AriCmshA_RCmlCIjE^Q4rKEOb76w3uNFpMM34(`2xF-Oh2gyV-7ZSyGDHiDnp= zhKcc^Wb296ESgJ6oTT^Wt}ymuQ_2%(Xfl^Tpg?FAAw){4T#=x4Eg6SY+oC{RLssqb dAdu>vkOf&rKGifn*7yJb002ovPDHLkV1n#Qo&f*= literal 0 HcmV?d00001 diff --git a/Android/app/src/main/res/drawable/green_pressed.9.png b/Android/app/src/main/res/drawable/green_pressed.9.png new file mode 100644 index 0000000000000000000000000000000000000000..42466f2b3a3cbc8522971cfd04a6749675bdb6fd GIT binary patch literal 383 zcmV-_0f7FAP)*gTZiG^kMDFVK7`{D^=H!CjS$y@W9y=QfhQGR6o% z48mH|HWIV(qnIPLCp|YojE@c%rKEOb5e7hpNFpMM1A>P{xF-Oh2gyV-7ZSyEDHOzWR05W)zn=ud-iDnp= zhKcbmRp*J;ESgJ6oMiCkt}ymulF}1rXfl^Tpg?FAAw(%9U6G)5Eg6So*P%dMZC35_ dAdu#rkOdEXK^n4$d5i!6002ovPDHLkV1g4}pxpof literal 0 HcmV?d00001 diff --git a/Android/app/src/main/res/drawable/ic_baseline_send.xml b/Android/app/src/main/res/drawable/ic_baseline_send.xml index 516b18892..a8a36dd94 100644 --- a/Android/app/src/main/res/drawable/ic_baseline_send.xml +++ b/Android/app/src/main/res/drawable/ic_baseline_send.xml @@ -6,6 +6,6 @@ android:viewportWidth="24" android:viewportHeight="24"> + android:fillColor="@color/green_mc" + android:pathData="M3.4,20.4l17.45,-7.48c0.81,-0.35 0.81,-1.49 0,-1.84L3.4,3.6c-0.66,-0.29 -1.39,0.2 -1.39,0.91L2,9.12c0,0.5 0.37,0.93 0.87,0.99L17,12 2.87,13.88c-0.5,0.07 -0.87,0.5 -0.87,1l0.01,4.61c0,0.71 0.73,1.2 1.39,0.91z" /> diff --git a/Android/app/src/main/res/drawable/loading.xml b/Android/app/src/main/res/drawable/loading.xml new file mode 100644 index 000000000..bc0d1d733 --- /dev/null +++ b/Android/app/src/main/res/drawable/loading.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + diff --git a/Android/app/src/main/res/drawable/loading_anim1.png b/Android/app/src/main/res/drawable/loading_anim1.png new file mode 100644 index 0000000000000000000000000000000000000000..33a98fb7aa276450bd754fc4bf749c26f4719bed GIT binary patch literal 1028 zcmV+f1pE7mP)C0000;P)t-s|NsA2 znbiOP|1(I|uG#;s+5aXz!co*1A-e_+WW5bEhaX)(78-x}^!g$moZrvqC?uvjOr>ch zlO6zf&9>XMlF4>AoReX(jET0W0000KbW%=J0RR90|NsC0|NsC0|NsC0|NsAhdRq?! z000A5NklP$c+9;9MESRbQAGWKkK*Nu_&1KI959w24i689H&$4WN4-SMs2_m-)HocZ zM^1vC$ORGWN>j}scEQdG- z5-J6Z_5B&;h$94$P%q$C?gNIN2(8%oETURKw*AP_1*G5Pv6M!Dj5CHjqKS{f|hgS&52LK)cdhk!c zT9WlyPN)`u91sH<6c7Sn;sEp_(W6a3&tc=`PjCPUGY6n&^RkWq-e4{I_B+6kP%;2g zeN3=6%Buz}i$BitaR3)JYRkoscV-VjKMoL4e+&?CI!VZip*msi0DgUZ33>Z7&>DtN zC4gfzO6ZXpQ3y2xxLACgMgh4ToZvq%ORWGBa{Vaa@tyOzzjuBA$5aSFY+?kN3XNFp z1idC2S_VD>&vA|K-}WKCL#_YZaxVf zfwbrqux%9soDj#rWo!L7;L_L{a|Sqp0Eh|JD?s!M2Qdi*pchY#ZTr)x5Ww~d2k0w> z020m}64C(cD+Q1M1Vp%KvjmMs`p3tvzg&8Nm^VOtK0sUh{H$k8==3zLtXII(6A5z# zjD|1{5IsTL?*Q});1W{G^a0_TiTWgfgvPmHy#u(0rA9wzK$Z~o4nPki+#W%`h>@Gw z1H@+rV6p(g0Jwyv4M-BAejJb;LG)b0H39?yBR$uU$pR#oo=XVk4TwWX4&X4r30k9P z0968d@P&j886h#l7vKm=K+wbrw!QI+4%>3NM2ykInDS00000C0000;P)t-s|NsA2 znbiOP|1(I|uG#;s+5aXz!co*1A-e_+WW5bEhaX)(78-xw&*vf@oXxh|C?uvjOr`kr z`W^sxwUWtcC6kk3v356{?G@qI0000KbW%=J0RR90|NsC0|NsC0|NsC0|NsAhdRq?! z000A2Nkl4 z`hYAB9BY8f{{=ka*aE(bcL(?*9??G_$@lxSv;8OM=WubMZ{ZpJ1JGX%_Iv4(lc1l- zK?&#QB=ihGj$Y`}=Ytx7s3FXs{MI{of7bxy=qtb>fee1?T|{&YKyLvgL_PQzNN5$X zq380*UF;A*Lcf5t_-rurMCcX^pCY;iq~%ABE^oXfuY?W(=u<$Aq9BWBlAZw3C!plD zw58we((-40(Ip^%0D%B8Lu%=>{(N8wZ355(8Ui4H{3M;?8Qvry3;=2b=%Jp0(vqxe zRYJdja|1D;K>;2B>jt0~L60_op3TNLSMUH5)(t?<;-!VZ8gN_i!6Tp`p=AI>y(g5` zWK+)Fl_!U#uR0J_R_gFA>{zF1m!=VyKm{c));dloNdU6KD&D&?SIv zw3RR;6E1`v0URu~owfp^97wSHyIrpU60&|P;O2|l+xdIy=YOU{0OGPpb} zq*H(rASZCJZt3p^5>M_2T>^m1r-<``2TbY1;4na1>AC&**d@T1c-|($hv17(LXALL z^a^-->KIT7J_Zik(r*Vm4xR>U22=t8;0dKyfS3mkViE{IFP;ZaPcMTG0W7bm0R2fJ zfCP>j#5n+crvMUw0EdG%C1^C#-`q^Swx9yUx&h+%0b1JESN-&a$xPF&(ktNknS_-B z@(_L(AZCJ=zXH%JfI~C}mKyzv0Xf0-6@VT{__+o7LtJuL zJwW_s07VKA41hyu&48TX`t5+U1<`W|_XrRKWIeF?AO%P+y?8rd-2fj#+<+Sam7v?` z891)Bs|Lec|r^zc(p zfe5 z$ literal 0 HcmV?d00001 diff --git a/Android/app/src/main/res/drawable/loading_anim3.png b/Android/app/src/main/res/drawable/loading_anim3.png new file mode 100644 index 0000000000000000000000000000000000000000..7614239f8ef966304593c98816b8426b9bd56c34 GIT binary patch literal 1024 zcmV+b1poVqP)C0000;P)t-s00012 znbiOP|1(I|uG#;s+5aXz!co*1A-e_+WW5bEhaX)(78-xew%Z~eoVAk4C?uvjOr_t? z=N`*5krL59z{|JW-ERAj{T>bneT$mWKLGu4u-!_JoCN(u z4ocYXN$44X9KARU_5(%`{Vp8Un!o`biq%2yYT#1^_t%^pMX$YDv~- zWkRpYM?9di$_30LeBtj`kH_i zkarE(Z1}h$p9XMHqedQFf3kW2`gwq;`a^+$<55CxG1N?0JAju@520Ls3)+MsbO~S^ z%@QKgQH9VWfP*Es(=5Qsp(JpBv*{H;g4fRiZa%rajce%RKhq%qaZ)45RA?pDnV|2W zQ-Bh{Cn!M7^mhY^gZn|B03n5s;8issqz{AB0BNP?_TyulfU?AKn}|9D79U7p1k$2c zz|&L5fJ~@k;IKtL50HKY4Au-!iB%BNngnOkOkcU0000C0000*P)t-s00012 znbiOP|1(I|uG#;s+5aXz!co*1A-e_+WW5bEhaX)(78-xGlF1?-oReX(C?uvjOr_1X z+a3USb~l{g&*%8``ddu!1^@s66m(KfQvm<}|NsC0|NsC0|NsC0|NsC0fO=aG1ONa7 zQ%OWYRCwC$mEm#{K@bMjBcOr?Fy{Rq)%*Oi_KmZ$m0#{qbQO1}5W3yjtREgcc<_Ec zcDU~V#AEI;Aj>~>7(^5gKx~!`@o$Kz8Zegcc27^c-|YWzIOru}M)d&npI3G}>6^SI z=qkA(V!tP$VgPdMg}z$L%?JcT@U`9b6AYqe0CMXIXple#SN|LdwF1x+Ktk3-90Lhe z0>*k@kq2?W0VLE5$Z|GV)BEZtztfMX7SLOMRzFwaX31tG%lfejp5rMRR=_+aj< zyGW=MfE-X0fEYr6C=tLRj2>+tj$y&};~NMdVb%cj{L1BkFDuIiFFyg$5^4rO*2e_2 zQC>A*S@=5Sw*oA((rV=5>lcP$NL{ z(LwA;0EAoW1nl34q+T1 zoS@|=z;W+W{rDgfS?>W<2*?QxAQR<6V=#Z~6(9-(qy+RC?a rC0000*P)t-s00012 znbiOP|1(I|uG#;s+5aXz!co*1A-e_+WW5bEhaX)(78-w(VX-0}oOU;yC?uvjOr^Dw z$sPcA&9>X$&*%8``s3(e;{X5v6m(KfQvm<}|NsC0|NsC0|NsC0|NsC0fO=aG1ONa7 zRY^oaRCodHmIrbhIt&H>kE(mu{f`R@ zJqbMnkfRre!F~`UfE+^n=I?R9^ScJ596bRQ63F29aX>_~0HY^>1gD2O1`?VDO!V=) z$`MxxAfaD?TYNScdLnd*g?AC%0^IT=N9Q-5lV?JQ0Q4>(N0E@lJx))6=o66gT-wxc zHg5U7KIszR-+(}Xh>%=*uip<$LW2PGfQA6@Z$C*x9N`@T`~V{`= zHk;$o$fp4u)TogMw_mItfPNkzs{T+Q;CPgfOAIv=)(+s|^Ft_?-+?w^2wei$Mze&7 zbW|bq2;gAJ?KBIpav-5x-)wpXkl^*RfV(g5@8fUi;~&!@0C7?y$W&-0)tR85pi_Vn zz$b99&h!t1P>aVwlK>bB7eN3+fRH{7&I6>Cp3BeAZ34;?$7Lew5LkR5fe}cHUI8yJ z9Ro-pfCLWP)XxK+2QPy)12TaCs0pc8fQSPJF$n~q7q5etm$yNO04* zu@6AsDS!kZpu$0G5(aSu-Q9)$`8fi_x&h+%0b1IpC;dK8fJoCN^bzp-O2SG3^C8Rw zL?meWGXT8;IE0k4egH!dRc``F7~Bt1p8*`hQlnopz$H{Y0jUQPer`cNh*J)$2Z-Mc zAaMbL0dNQ{8(OVee#QFh1Lf`|C6Jr*C1SkPI1o%O?jPs3${xm?3x+b7+5I_VOhFEg+ zFE7$duD?D3eV+g#d`9YDK0#aqxYRd*2*(SgJ_Gy)Y#IPAfft_#pzj{wNNG*++wT$s tGQtI<{DK2ag4bVi0C@GX0avbE`3rk|T9o|RxOM;l002ovPDHLkV1izlyu$zh literal 0 HcmV?d00001 diff --git a/Android/app/src/main/res/drawable/loading_anim6.png b/Android/app/src/main/res/drawable/loading_anim6.png new file mode 100644 index 0000000000000000000000000000000000000000..e8cce7bb6bda0f77d04e90e1438a3200aa6ae4b0 GIT binary patch literal 1015 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 literal 0 HcmV?d00001 diff --git a/Android/app/src/main/res/drawable/progress.xml b/Android/app/src/main/res/drawable/progress.xml deleted file mode 100644 index 935315178..000000000 --- a/Android/app/src/main/res/drawable/progress.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/Android/app/src/main/res/drawable/progress_bar.webp b/Android/app/src/main/res/drawable/progress_bar.webp deleted file mode 100644 index fa9667392b58faf279656592f0b94d042b1b20f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 218 zcmV<0044uYNk&G}00012MM6+kP&iD+0000l|G^IsCouo>KmP&}GG&Gw5C9*D;3~G= zxRD$KkQjJe0+}iRHt{Fr_3w3WME@s%J_@bs>wf&YC%*2>uY2?B c{`|fNzVE~Dd-3~z_`WB<@B0|~-uS-10BNCj0{{R3 diff --git a/Android/app/src/main/res/drawable/progress_bar_fg.png b/Android/app/src/main/res/drawable/progress_bar_fg.png deleted file mode 100644 index 0f873f69a27ebbf58ca0cbbd4fa9b91b0bce9e99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 222 zcmeAS@N?(olHy`uVBq!ia0y~yU;;8392h~Q%aKn)K#Hj($S;_Ip=|P53m|X0r;B4q z1>@W68+i{K@VHzwj@j{rLsE6|(Z!V_{R@m-CwQym9*937@PloK6U&jsvz{23&OWRc z%HO^>bg#^}tM`*0OxPl2@mqRR_#NIUb}VLX%NzaYE6rXkD7WC~iG$2x%If?#dSc8u zZuCy!nW3h@Y?RQZpZh0HV!!n9@62(91t$-g@{9Y%losAhE0vd*`SawVySV-DOZ>Hr VWryZY|H}_@xTmY1%Q~loCIBCiQXv2U diff --git a/Android/app/src/main/res/drawable/red.9.png b/Android/app/src/main/res/drawable/red.9.png new file mode 100644 index 0000000000000000000000000000000000000000..9de391cb25334e5463f7b859f0249acb3def1f59 GIT binary patch literal 374 zcmV-+0g3*JP)8!8NPgn26#{d8T$~HfDA0tr}8P#BBtt~a+h>X~3 zZ=WhK)L&)RWNX}bfB*mgLb$xc00001bW%=J06^y0W&i*H+(|@1RCr#+(%DW#F$jR+ zLie8i%;NjMskETX*qYJA#Q*w(8!&y-WCqRiKCDeJ2q^{Xpxj3QaPG)tK1wO+6FEgW zTVzt+!fhClrII<6CeANaW369^?5PMCATK0|xIH9BNMOQ1dnPPKMhT1SL(M1&j6tE4w)BaumV0HenQxMN%^ z$=Qj~L@3#+c~$^bToH*>W5sAHOe40-dmm#&WI|moy=e&7)evc6*Fsg$$n+xf4ov?~|L}FFN$Nz0xW(_tMqpRAKt&=j?lf<1jw}007e|G;|di>TY0|?mw#%BcZLWa*EWFyjDcs6@*TQFZW+30siPgYj%C0w2Miu}7 z0MffzpNT8~|Nq;_dDXsP$&tjV00001bW%=J06^y0W&i*H-AP12RCr#+(%EhUF$h3W zgLlt9N!tJa(;7@lQoBkkRqA~{hzBrz=V=D*`!tLv8gSmb+FG;s0AQZ5k$nvz_)laN z#h9>>aC7g&Dp`o^F0h!tL?)%YR5JM>V1Tj^FXC~B7$J^{0PUHG7#Jl@TpnVh#8ods zYpaB;PDE#ZMOOHC0z&L7a{dW1KOz>sIe?N4V0=b^qGb3CN;V?BnVFPEq6HW|Ccqn( zgGh{4j3z?KM&?-okhmaLLMDmPR2U|yE9YEFLA(=lz4nF?9)}@9Vb@Y4z~p?9`2ehJ VJR1F>JA(iK002ovPDHLkV1kZEpQiu- literal 0 HcmV?d00001 diff --git a/Android/app/src/main/res/drawable/yellow_pressed.9.png b/Android/app/src/main/res/drawable/yellow_pressed.9.png new file mode 100644 index 0000000000000000000000000000000000000000..e3e3f76d5962548441aaf42409e68a764196b088 GIT binary patch literal 375 zcmV--0f_#IP)B>f3gXdnf1A zYV6y7yreYi*mM8?|L)%GLg9}01^vgB4iYqDi$IWRVAf#&LN&eY+G$I!f_NtD6E=O1TrxXi7!Ao VI#4!I$KwD1002ovPDHLkV1jqMqcZ>i literal 0 HcmV?d00001 diff --git a/Android/app/src/main/res/layout/activity_main.xml b/Android/app/src/main/res/layout/activity_main.xml index 020858e58..c9532e99c 100644 --- a/Android/app/src/main/res/layout/activity_main.xml +++ b/Android/app/src/main/res/layout/activity_main.xml @@ -1,34 +1,22 @@ - + android:layout_height="match_parent" + android:gravity="center" + android:orientation="vertical"> - - - + - - + android:textSize="16sp" /> + diff --git a/Android/app/src/main/res/layout/conn_dialog.xml b/Android/app/src/main/res/layout/conn_dialog.xml deleted file mode 100644 index f47376794..000000000 --- a/Android/app/src/main/res/layout/conn_dialog.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/Android/app/src/main/res/layout/connection_dialog.xml b/Android/app/src/main/res/layout/connection_dialog.xml new file mode 100644 index 000000000..8d825ccca --- /dev/null +++ b/Android/app/src/main/res/layout/connection_dialog.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + diff --git a/Android/app/src/main/res/layout/input_text.xml b/Android/app/src/main/res/layout/input_text.xml index 758ea6c5f..5d0867c81 100644 --- a/Android/app/src/main/res/layout/input_text.xml +++ b/Android/app/src/main/res/layout/input_text.xml @@ -6,16 +6,17 @@ + app:endIconTint="@null" + app:hintTextColor="@color/green_mc"> + app:endIconTint="@null" + app:hintTextColor="@color/green_mc"> - + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:baselineAligned="false" + android:gravity="center" + android:weightSum="1"> + android:padding="16dp" + tools:ignore="UselessParent"> + android:textColor="@color/grey_900" /> + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="8dp"> - + android:textColor="@color/grey_900" + android:textSize="16sp" /> + android:layout_height="wrap_content" + android:layout_marginTop="8dp"> - + android:textAllCaps="false" + android:textColor="@android:color/white" /> - + android:textAllCaps="false" + android:textColor="@android:color/white" /> - + diff --git a/Android/app/src/main/res/mipmap/ic_dialog.png b/Android/app/src/main/res/mipmap/ic_dialog.png new file mode 100644 index 0000000000000000000000000000000000000000..12db56f1ed8335759f78fe5e83cf04fcb1ce98a9 GIT binary patch literal 4856 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 e`qv@4)BX>_$NV + Подготовка к запуску… Загрузка… Загрузка MultiCraft @@ -9,9 +10,8 @@ Нет Интернет Подключения! - Для полноценной игры, MultiCraft требует подключение к Интернету.\nВ противном случае вам будет недоступно Обновление игры и режим Мультиплеера! - 3G/4G - Игнорировать + Для полноценной игры, MultiCraft требует подключение к Интернету.\nВ противном случае Обновление игры и режим Мультиплеера будут недоступны! + Пропустить Нам очень жаль! diff --git a/Android/app/src/main/res/values-sw600dp/attrs.xml b/Android/app/src/main/res/values-sw600dp/attrs.xml deleted file mode 100644 index fccd39d6a..000000000 --- a/Android/app/src/main/res/values-sw600dp/attrs.xml +++ /dev/null @@ -1,3 +0,0 @@ - - true - diff --git a/Android/app/src/main/res/values-v26/styles.xml b/Android/app/src/main/res/values-v26/styles.xml new file mode 100644 index 000000000..8a2fe0338 --- /dev/null +++ b/Android/app/src/main/res/values-v26/styles.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/Android/app/src/main/res/values-v27/styles.xml b/Android/app/src/main/res/values-v27/styles.xml new file mode 100644 index 000000000..6e004ae79 --- /dev/null +++ b/Android/app/src/main/res/values-v27/styles.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/Android/app/src/main/res/values/attrs.xml b/Android/app/src/main/res/values/attrs.xml deleted file mode 100644 index 934d5c83d..000000000 --- a/Android/app/src/main/res/values/attrs.xml +++ /dev/null @@ -1,3 +0,0 @@ - - false - diff --git a/Android/app/src/main/res/values/colors.xml b/Android/app/src/main/res/values/colors.xml index a4deeb54d..1aaa212f8 100644 --- a/Android/app/src/main/res/values/colors.xml +++ b/Android/app/src/main/res/values/colors.xml @@ -1,8 +1,6 @@ - #008C80 #FAFAFA #121212 - #FF1744 #32783C #212121 diff --git a/Android/app/src/main/res/values/strings.xml b/Android/app/src/main/res/values/strings.xml index d14e0fa83..bc750c70a 100644 --- a/Android/app/src/main/res/values/strings.xml +++ b/Android/app/src/main/res/values/strings.xml @@ -1,11 +1,12 @@ MultiCraft - + Preparing to launch… Loading… Loading MultiCraft Less than 1 minute… + Enter text Enter password @@ -13,7 +14,7 @@ No Internet Connection! MultiCraft requires an Internet connection to use all game features.\nOtherwise, you will not get Updates and Multiplayer mode will be not available! Wi-Fi - Mobile Data + LTE Ignore diff --git a/Android/app/src/main/res/values/styles.xml b/Android/app/src/main/res/values/styles.xml index 0daff9289..eb01b5255 100644 --- a/Android/app/src/main/res/values/styles.xml +++ b/Android/app/src/main/res/values/styles.xml @@ -1,27 +1,25 @@ + - - - - + diff --git a/Android/native/build.gradle b/Android/native/build.gradle index 31a1e2a17..0fcb12e75 100644 --- a/Android/native/build.gradle +++ b/Android/native/build.gradle @@ -2,12 +2,12 @@ apply plugin: 'com.android.library' apply plugin: 'de.undercouch.download' android { - compileSdkVersion 33 - buildToolsVersion '33.0.2' + compileSdkVersion 34 + buildToolsVersion '34.0.0' ndkVersion '25.2.9519653' defaultConfig { minSdkVersion 21 - targetSdkVersion 33 + targetSdkVersion 34 externalNativeBuild { ndkBuild { arguments '-j' + Runtime.getRuntime().availableProcessors(),