Android: latest bugfixes and features (#39)
Co-authored-by: Maksim <MoNTE48@mail.ua>
This commit is contained in:
parent
e03170fb77
commit
db273c4645
@ -2,13 +2,13 @@ apply plugin: 'com.android.application'
|
|||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 31
|
compileSdkVersion 32
|
||||||
buildToolsVersion '31.0.0'
|
buildToolsVersion '32.0.0'
|
||||||
ndkVersion '23.1.7779620'
|
ndkVersion '23.1.7779620'
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId 'com.multicraft.game'
|
applicationId 'com.multicraft.game'
|
||||||
minSdkVersion 19
|
minSdkVersion 21
|
||||||
targetSdkVersion 31
|
targetSdkVersion 32
|
||||||
versionName "${versionMajor}.${versionMinor}.${versionPatch}"
|
versionName "${versionMajor}.${versionMinor}.${versionPatch}"
|
||||||
versionCode project.versionCode
|
versionCode project.versionCode
|
||||||
}
|
}
|
||||||
@ -135,9 +135,9 @@ dependencies {
|
|||||||
implementation project(':native')
|
implementation project(':native')
|
||||||
|
|
||||||
/* Third-party libraries */
|
/* Third-party libraries */
|
||||||
implementation 'androidx.appcompat:appcompat:1.4.0'
|
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||||
implementation 'androidx.appcompat:appcompat-resources:1.4.0'
|
implementation 'androidx.appcompat:appcompat-resources:1.4.1'
|
||||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'
|
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.1'
|
||||||
implementation 'androidx.work:work-runtime-ktx:2.7.1'
|
implementation 'androidx.work:work-runtime-ktx:2.7.1'
|
||||||
implementation 'com.google.android.material:material:1.4.0'
|
implementation 'com.google.android.material:material:1.5.0'
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@ import static android.text.InputType.TYPE_CLASS_TEXT;
|
|||||||
import static android.text.InputType.TYPE_TEXT_FLAG_MULTI_LINE;
|
import static android.text.InputType.TYPE_TEXT_FLAG_MULTI_LINE;
|
||||||
import static android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD;
|
import static android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD;
|
||||||
import static com.multicraft.game.helpers.Utilities.finishApp;
|
import static com.multicraft.game.helpers.Utilities.finishApp;
|
||||||
import static com.multicraft.game.helpers.Utilities.getTotalMem;
|
|
||||||
import static com.multicraft.game.helpers.Utilities.makeFullScreen;
|
import static com.multicraft.game.helpers.Utilities.makeFullScreen;
|
||||||
|
|
||||||
import android.app.NativeActivity;
|
import android.app.NativeActivity;
|
||||||
@ -104,7 +103,6 @@ public class GameActivity extends NativeActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public void showDialog(String s, String hint, String current, int editType) {
|
public void showDialog(String s, String hint, String current, int editType) {
|
||||||
runOnUiThread(() -> showDialogUI(hint, current, editType));
|
runOnUiThread(() -> showDialogUI(hint, current, editType));
|
||||||
}
|
}
|
||||||
@ -164,7 +162,6 @@ public class GameActivity extends NativeActivity {
|
|||||||
return messageReturnCode;
|
return messageReturnCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public String getDialogValue() {
|
public String getDialogValue() {
|
||||||
messageReturnCode = -1;
|
messageReturnCode = -1;
|
||||||
return messageReturnValue;
|
return messageReturnValue;
|
||||||
@ -174,10 +171,6 @@ public class GameActivity extends NativeActivity {
|
|||||||
return getResources().getDisplayMetrics().density;
|
return getResources().getDisplayMetrics().density;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getMemoryMax() {
|
|
||||||
return getTotalMem(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void notifyServerConnect(boolean multiplayer) {
|
public void notifyServerConnect(boolean multiplayer) {
|
||||||
isMultiPlayer = multiplayer;
|
isMultiPlayer = multiplayer;
|
||||||
}
|
}
|
||||||
@ -185,7 +178,6 @@ public class GameActivity extends NativeActivity {
|
|||||||
public void notifyExitGame() {
|
public void notifyExitGame() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public void openURI(String uri) {
|
public void openURI(String uri) {
|
||||||
try {
|
try {
|
||||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
||||||
@ -194,12 +186,13 @@ public class GameActivity extends NativeActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public void finishGame(String exc) {
|
public void finishGame(String exc) {
|
||||||
finishApp(true, this);
|
finishApp(true, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public void handleError(String exc) {
|
public void handleError(String exc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void upgrade(String item) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
package com.multicraft.game
|
package com.multicraft.game
|
||||||
|
|
||||||
import android.content.DialogInterface
|
import android.content.*
|
||||||
import android.content.Intent
|
|
||||||
import android.content.SharedPreferences
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.drawable.LayerDrawable
|
import android.graphics.drawable.LayerDrawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@ -34,9 +32,7 @@ import androidx.appcompat.app.AlertDialog
|
|||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.graphics.BlendModeColorFilterCompat
|
import androidx.core.graphics.BlendModeColorFilterCompat
|
||||||
import androidx.core.graphics.BlendModeCompat
|
import androidx.core.graphics.BlendModeCompat
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.*
|
||||||
import androidx.lifecycle.ViewModelProvider
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import androidx.work.WorkInfo
|
import androidx.work.WorkInfo
|
||||||
import com.multicraft.game.databinding.ActivityMainBinding
|
import com.multicraft.game.databinding.ActivityMainBinding
|
||||||
import com.multicraft.game.helpers.Constants.NO_SPACE_LEFT
|
import com.multicraft.game.helpers.Constants.NO_SPACE_LEFT
|
||||||
@ -51,10 +47,10 @@ import com.multicraft.game.helpers.PreferenceHelper.getStringValue
|
|||||||
import com.multicraft.game.helpers.PreferenceHelper.set
|
import com.multicraft.game.helpers.PreferenceHelper.set
|
||||||
import com.multicraft.game.helpers.Utilities.addShortcut
|
import com.multicraft.game.helpers.Utilities.addShortcut
|
||||||
import com.multicraft.game.helpers.Utilities.copyInputStreamToFile
|
import com.multicraft.game.helpers.Utilities.copyInputStreamToFile
|
||||||
import com.multicraft.game.helpers.Utilities.finishApp
|
|
||||||
import com.multicraft.game.helpers.Utilities.getIcon
|
import com.multicraft.game.helpers.Utilities.getIcon
|
||||||
import com.multicraft.game.helpers.Utilities.isConnected
|
import com.multicraft.game.helpers.Utilities.isConnected
|
||||||
import com.multicraft.game.helpers.Utilities.makeFullScreen
|
import com.multicraft.game.helpers.Utilities.makeFullScreen
|
||||||
|
import com.multicraft.game.helpers.Utilities.showRestartDialog
|
||||||
import com.multicraft.game.workmanager.UnzipWorker.Companion.PROGRESS
|
import com.multicraft.game.workmanager.UnzipWorker.Companion.PROGRESS
|
||||||
import com.multicraft.game.workmanager.WorkerViewModel
|
import com.multicraft.game.workmanager.WorkerViewModel
|
||||||
import com.multicraft.game.workmanager.WorkerViewModelFactory
|
import com.multicraft.game.workmanager.WorkerViewModelFactory
|
||||||
@ -75,17 +71,14 @@ class MainActivity : AppCompatActivity() {
|
|||||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
prefs = PreferenceHelper.init(this)
|
prefs = PreferenceHelper.init(this)
|
||||||
var storageUnavailable = false
|
|
||||||
try {
|
try {
|
||||||
externalStorage = getExternalFilesDir(null)
|
externalStorage = getExternalFilesDir(null)
|
||||||
if (filesDir == null || cacheDir == null || externalStorage == null)
|
if (filesDir == null || cacheDir == null || externalStorage == null)
|
||||||
throw IOException("Bad disk space state")
|
throw IOException("Bad disk space state")
|
||||||
|
lateInit()
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
storageUnavailable = true
|
showRestartDialog(this, !e.message!!.contains(NO_SPACE_LEFT))
|
||||||
showRestartDialog(e.message!!.contains(NO_SPACE_LEFT))
|
|
||||||
}
|
}
|
||||||
if (storageUnavailable) return
|
|
||||||
lateInit()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
@ -153,7 +146,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
} else {
|
} else {
|
||||||
prefs[TAG_BUILD_VER] = "0"
|
prefs[TAG_BUILD_VER] = "0"
|
||||||
showRestartDialog(false)
|
showRestartDialog(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,11 +173,20 @@ class MainActivity : AppCompatActivity() {
|
|||||||
File(cacheDir, it).copyInputStreamToFile(input)
|
File(cacheDir, it).copyInputStreamToFile(input)
|
||||||
}
|
}
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
runOnUiThread { showRestartDialog(e.message!!.contains(NO_SPACE_LEFT)) }
|
runOnUiThread {
|
||||||
|
showRestartDialog(
|
||||||
|
this@MainActivity,
|
||||||
|
!e.message!!.contains(NO_SPACE_LEFT)
|
||||||
|
)
|
||||||
|
}
|
||||||
return@forEach
|
return@forEach
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
startUnzipWorker(zips)
|
try {
|
||||||
|
startUnzipWorker(zips)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
runOnUiThread { showRestartDialog(this@MainActivity) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,7 +221,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
if (workInfo.state.isFinished) {
|
if (workInfo.state.isFinished) {
|
||||||
if (workInfo.state == WorkInfo.State.FAILED) {
|
if (workInfo.state == WorkInfo.State.FAILED) {
|
||||||
showRestartDialog(false)
|
showRestartDialog(this)
|
||||||
} else if (workInfo.state == WorkInfo.State.SUCCEEDED) {
|
} else if (workInfo.state == WorkInfo.State.SUCCEEDED) {
|
||||||
prefs[TAG_BUILD_VER] = versionName
|
prefs[TAG_BUILD_VER] = versionName
|
||||||
startNative()
|
startNative()
|
||||||
@ -229,17 +231,6 @@ class MainActivity : AppCompatActivity() {
|
|||||||
viewModel.startOneTimeWorkRequest()
|
viewModel.startOneTimeWorkRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showRestartDialog(space: Boolean) {
|
|
||||||
val message = if (space) getString(R.string.no_space) else getString(R.string.restart)
|
|
||||||
val builder = AlertDialog.Builder(this)
|
|
||||||
builder.setMessage(message)
|
|
||||||
.setPositiveButton(R.string.ok) { _, _ -> finishApp(!space, this) }
|
|
||||||
.setCancelable(false)
|
|
||||||
val dialog = builder.create()
|
|
||||||
makeFullScreen(dialog.window!!)
|
|
||||||
if (!isFinishing) dialog.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
// connection dialog
|
// connection dialog
|
||||||
private fun showConnectionDialog() {
|
private fun showConnectionDialog() {
|
||||||
val builder = AlertDialog.Builder(this)
|
val builder = AlertDialog.Builder(this)
|
||||||
|
@ -26,9 +26,9 @@ import android.os.Build.VERSION_CODES.*
|
|||||||
object ApiLevelHelper {
|
object ApiLevelHelper {
|
||||||
private fun isGreaterOrEqual(versionCode: Int) = SDK_INT >= versionCode
|
private fun isGreaterOrEqual(versionCode: Int) = SDK_INT >= versionCode
|
||||||
|
|
||||||
fun isLollipop() = isGreaterOrEqual(LOLLIPOP)
|
|
||||||
|
|
||||||
fun isMarshmallow() = isGreaterOrEqual(M)
|
fun isMarshmallow() = isGreaterOrEqual(M)
|
||||||
|
|
||||||
fun isOreo() = isGreaterOrEqual(O)
|
fun isOreo() = isGreaterOrEqual(O)
|
||||||
|
|
||||||
|
fun isAndroid12() = isGreaterOrEqual(S)
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
package com.multicraft.game.helpers
|
package com.multicraft.game.helpers
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.ActivityManager
|
import android.app.ActivityManager
|
||||||
import android.app.AlarmManager
|
import android.app.AlarmManager
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
|
import android.app.PendingIntent.FLAG_CANCEL_CURRENT
|
||||||
|
import android.app.PendingIntent.FLAG_IMMUTABLE
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
@ -32,8 +33,8 @@ import android.graphics.Bitmap
|
|||||||
import android.graphics.drawable.BitmapDrawable
|
import android.graphics.drawable.BitmapDrawable
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
|
import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
|
||||||
import android.view.View
|
|
||||||
import android.view.Window
|
import android.view.Window
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
@ -43,41 +44,24 @@ import androidx.core.view.WindowInsetsControllerCompat
|
|||||||
import androidx.core.view.WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
import androidx.core.view.WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||||
import com.multicraft.game.MainActivity
|
import com.multicraft.game.MainActivity
|
||||||
import com.multicraft.game.R
|
import com.multicraft.game.R
|
||||||
import com.multicraft.game.helpers.ApiLevelHelper.isLollipop
|
import com.multicraft.game.databinding.RestartDialogBinding
|
||||||
|
import com.multicraft.game.helpers.ApiLevelHelper.isAndroid12
|
||||||
import com.multicraft.game.helpers.ApiLevelHelper.isMarshmallow
|
import com.multicraft.game.helpers.ApiLevelHelper.isMarshmallow
|
||||||
import com.multicraft.game.helpers.ApiLevelHelper.isOreo
|
import com.multicraft.game.helpers.ApiLevelHelper.isOreo
|
||||||
import com.multicraft.game.helpers.PreferenceHelper.TAG_SHORTCUT_EXIST
|
import com.multicraft.game.helpers.PreferenceHelper.TAG_SHORTCUT_EXIST
|
||||||
import com.multicraft.game.helpers.PreferenceHelper.set
|
import com.multicraft.game.helpers.PreferenceHelper.set
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import kotlin.math.roundToInt
|
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
object Utilities {
|
object Utilities {
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun getTotalMem(context: Context): Float {
|
|
||||||
val actManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
|
|
||||||
val memInfo = ActivityManager.MemoryInfo()
|
|
||||||
actManager.getMemoryInfo(memInfo)
|
|
||||||
var memory = memInfo.totalMem * 1.0f / (1024 * 1024 * 1024)
|
|
||||||
memory = (memory * 100).roundToInt() / 100.0f
|
|
||||||
return memory
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun makeFullScreen(window: Window) {
|
fun makeFullScreen(window: Window) {
|
||||||
if (isLollipop()) {
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
WindowInsetsControllerCompat(window, window.decorView).let {
|
||||||
WindowInsetsControllerCompat(window, window.decorView).let {
|
it.hide(statusBars() or navigationBars())
|
||||||
it.hide(statusBars() or navigationBars())
|
it.systemBarsBehavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||||
it.systemBarsBehavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
|
||||||
}
|
|
||||||
} else @Suppress("DEPRECATION") {
|
|
||||||
val decor = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
|
|
||||||
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
|
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
|
||||||
window.decorView.systemUiVisibility = decor
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,19 +94,39 @@ object Utilities {
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun finishApp(restart: Boolean, activity: Activity) {
|
fun finishApp(restart: Boolean, activity: Activity) {
|
||||||
if (restart) @SuppressLint("UnspecifiedImmutableFlag") {
|
if (restart) {
|
||||||
val intent = Intent(activity, activity::class.java)
|
val intent = Intent(activity, activity::class.java)
|
||||||
val mPendingIntentId = 1337
|
val mPendingIntentId = 1337
|
||||||
|
val flag = if (isAndroid12()) FLAG_IMMUTABLE else FLAG_CANCEL_CURRENT
|
||||||
val mgr = activity.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
val mgr = activity.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||||
mgr.set(
|
mgr.set(
|
||||||
AlarmManager.RTC, System.currentTimeMillis(), PendingIntent.getActivity(
|
AlarmManager.RTC, System.currentTimeMillis(), PendingIntent.getActivity(
|
||||||
activity, mPendingIntentId, intent, PendingIntent.FLAG_CANCEL_CURRENT
|
activity, mPendingIntentId, intent, flag
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
exitProcess(0)
|
exitProcess(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun showRestartDialog(activity: Activity, isRestart: Boolean = true) {
|
||||||
|
val message =
|
||||||
|
if (isRestart) activity.getString(R.string.restart) else activity.getString(R.string.no_space)
|
||||||
|
val builder = AlertDialog.Builder(activity)
|
||||||
|
builder.setIcon(getIcon(activity))
|
||||||
|
val binding = RestartDialogBinding.inflate(activity.layoutInflater)
|
||||||
|
builder.setView(binding.root)
|
||||||
|
val dialog = builder.create()
|
||||||
|
binding.errorDesc.text = message
|
||||||
|
binding.close.setOnClickListener {
|
||||||
|
dialog.dismiss()
|
||||||
|
finishApp(!isRestart, activity)
|
||||||
|
}
|
||||||
|
binding.restart.setOnClickListener { finishApp(isRestart, activity) }
|
||||||
|
dialog.window?.setBackgroundDrawableResource(R.drawable.custom_dialog_rounded_daynight)
|
||||||
|
makeFullScreen(dialog.window!!)
|
||||||
|
dialog.show()
|
||||||
|
}
|
||||||
|
|
||||||
fun File.copyInputStreamToFile(inputStream: InputStream) =
|
fun File.copyInputStreamToFile(inputStream: InputStream) =
|
||||||
this.outputStream().use { fileOut -> inputStream.copyTo(fileOut, 8192) }
|
this.outputStream().use { fileOut -> inputStream.copyTo(fileOut, 8192) }
|
||||||
|
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="?attr/colorBackgroundFloating" />
|
||||||
|
<corners android:radius="12dp" />
|
||||||
|
</shape>
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="@color/not_white" />
|
||||||
|
<corners android:radius="12dp" />
|
||||||
|
</shape>
|
BIN
build/android/app/src/main/res/drawable/sad.png
Normal file
BIN
build/android/app/src/main/res/drawable/sad.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.0 KiB |
86
build/android/app/src/main/res/layout/restart_dialog.xml
Normal file
86
build/android/app/src/main/res/layout/restart_dialog.xml
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingHorizontal="10dp"
|
||||||
|
android:paddingTop="10dp">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
android:text="@string/sorry"
|
||||||
|
android:textSize="22sp" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:contentDescription="@string/restart"
|
||||||
|
android:paddingStart="12dp"
|
||||||
|
android:paddingTop="4dp"
|
||||||
|
android:paddingEnd="12dp"
|
||||||
|
android:paddingBottom="4dp"
|
||||||
|
android:src="@drawable/sad" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/error_desc"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:minHeight="128dp"
|
||||||
|
android:paddingStart="4dp"
|
||||||
|
android:paddingTop="4dp"
|
||||||
|
android:paddingEnd="4dp"
|
||||||
|
android:paddingBottom="4dp"
|
||||||
|
android:text="@string/restart"
|
||||||
|
android:textSize="15sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/close"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:layout_weight="0.5"
|
||||||
|
android:text="@string/close_game"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/restart"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:layout_weight="0.5"
|
||||||
|
android:text="@string/restart_game"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
@ -6,8 +6,6 @@
|
|||||||
<string name="loadingp">Загрузка… %d%%</string>
|
<string name="loadingp">Загрузка… %d%%</string>
|
||||||
<string name="notification_title">Загрузка MultiCraft</string>
|
<string name="notification_title">Загрузка MultiCraft</string>
|
||||||
<string name="notification_description">Осталось меньше минуты…</string>
|
<string name="notification_description">Осталось меньше минуты…</string>
|
||||||
<string name="restart">Произошла ошибка, игра будет перезапущена автоматически</string>
|
|
||||||
<string name="no_space">Недостаточно места для записи файлов игры, пожалуйста освободите место в памяти</string>
|
|
||||||
|
|
||||||
<string name="input_text">Введите Текст</string>
|
<string name="input_text">Введите Текст</string>
|
||||||
<string name="input_password">Пароль</string>
|
<string name="input_password">Пароль</string>
|
||||||
@ -19,4 +17,10 @@
|
|||||||
<string name="conn_mobile">3G/4G</string>
|
<string name="conn_mobile">3G/4G</string>
|
||||||
<string name="ignore">Игнорировать</string>
|
<string name="ignore">Игнорировать</string>
|
||||||
|
|
||||||
|
<!-- Crash -->
|
||||||
|
<string name="sorry">Нам очень жаль!</string>
|
||||||
|
<string name="restart">К сожалению, произошла непредвиденная ошибка, хотите перезапустить игру?</string>
|
||||||
|
<string name="no_space">Недостаточно места для записи файлов игры, пожалуйста освободите место на диске</string>
|
||||||
|
<string name="close_game">Закрыть игру</string>
|
||||||
|
<string name="restart_game">Перезапустить</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
<color name="green">#008c80</color>
|
||||||
<color name="not_white">#fefefe</color>
|
<color name="not_white">#fefefe</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -8,8 +8,6 @@
|
|||||||
<string name="loadingp">Loading… %d%%</string>
|
<string name="loadingp">Loading… %d%%</string>
|
||||||
<string name="notification_title">Loading MultiCraft</string>
|
<string name="notification_title">Loading MultiCraft</string>
|
||||||
<string name="notification_description">Less than 1 minute…</string>
|
<string name="notification_description">Less than 1 minute…</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="ok" translatable="false">OK</string>
|
<string name="ok" translatable="false">OK</string>
|
||||||
|
|
||||||
<string name="input_text">Text Input</string>
|
<string name="input_text">Text Input</string>
|
||||||
@ -23,4 +21,10 @@
|
|||||||
<string name="conn_mobile">Mobile Data</string>
|
<string name="conn_mobile">Mobile Data</string>
|
||||||
<string name="ignore">Ignore</string>
|
<string name="ignore">Ignore</string>
|
||||||
|
|
||||||
|
<!-- Crash -->
|
||||||
|
<string name="sorry">We are sorry!</string>
|
||||||
|
<string name="restart">Unfortunately, unexpected issue was happened, would you like to restart the app?</string>
|
||||||
|
<string name="no_space">No space left for game files, please free up space on the disk before restarting the app</string>
|
||||||
|
<string name="close_game">Close game</string>
|
||||||
|
<string name="restart_game">Restart</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
<item name="android:windowFullscreen">true</item>
|
<item name="android:windowFullscreen">true</item>
|
||||||
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="p">shortEdges</item>
|
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="p">shortEdges</item>
|
||||||
<item name="fontFamily">@font/multicraftfont</item>
|
<item name="fontFamily">@font/multicraftfont</item>
|
||||||
|
<item name="colorControlActivated">@color/green</item>
|
||||||
|
<item name="colorPrimary">@color/green</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -15,9 +15,9 @@ buildscript {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.0.3'
|
classpath 'com.android.tools.build:gradle:7.1.1'
|
||||||
classpath 'de.undercouch:gradle-download-task:4.1.2'
|
classpath 'de.undercouch:gradle-download-task:4.1.2'
|
||||||
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0'
|
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10'
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#Thu Nov 11 00:49:46 CET 2021
|
#Fri Feb 11 12:29:43 EET 2022
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
@ -2,12 +2,12 @@ apply plugin: 'com.android.library'
|
|||||||
apply plugin: 'de.undercouch.download'
|
apply plugin: 'de.undercouch.download'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 31
|
compileSdkVersion 32
|
||||||
buildToolsVersion '31.0.0'
|
buildToolsVersion '32.0.0'
|
||||||
ndkVersion '23.1.7779620'
|
ndkVersion '23.1.7779620'
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 19
|
minSdkVersion 21
|
||||||
targetSdkVersion 31
|
targetSdkVersion 32
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
ndkBuild {
|
ndkBuild {
|
||||||
arguments '-j' + Runtime.getRuntime().availableProcessors(),
|
arguments '-j' + Runtime.getRuntime().availableProcessors(),
|
||||||
|
@ -4474,10 +4474,16 @@ void the_game(bool *kill,
|
|||||||
} catch (ServerError &e) {
|
} catch (ServerError &e) {
|
||||||
error_message = e.what();
|
error_message = e.what();
|
||||||
errorstream << "ServerError: " << error_message << std::endl;
|
errorstream << "ServerError: " << error_message << std::endl;
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
porting::handleError("ServerError", error_message);
|
||||||
|
#endif
|
||||||
} catch (ModError &e) {
|
} catch (ModError &e) {
|
||||||
error_message = std::string("ModError: ") + e.what() +
|
error_message = std::string("ModError: ") + e.what() +
|
||||||
strgettext("\nCheck debug.txt for details.");
|
strgettext("\nCheck debug.txt for details.");
|
||||||
errorstream << error_message << std::endl;
|
errorstream << error_message << std::endl;
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
porting::handleError("ModError", error_message);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
g_game = NULL;
|
g_game = NULL;
|
||||||
game.shutdown();
|
game.shutdown();
|
||||||
|
@ -56,7 +56,15 @@ void sanity_check_fn(const char *assertion, const char *file,
|
|||||||
errorstream << file << ":" << line << ": " << function
|
errorstream << file << ":" << line << ": " << function
|
||||||
<< ": An engine assumption '" << assertion << "' failed." << std::endl;
|
<< ": An engine assumption '" << assertion << "' failed." << std::endl;
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
std::string capture = "An engine assumption failed: \"" + std::string(assertion) +
|
||||||
|
"\" in file: " + std::string(file) + ":" + std::to_string(line) +
|
||||||
|
" (" + std::string(function) + ")";
|
||||||
|
|
||||||
|
throw std::runtime_error(capture);
|
||||||
|
#else
|
||||||
abort();
|
abort();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void fatal_error_fn(const char *msg, const char *file,
|
void fatal_error_fn(const char *msg, const char *file,
|
||||||
@ -71,7 +79,15 @@ void fatal_error_fn(const char *msg, const char *file,
|
|||||||
errorstream << file << ":" << line << ": " << function
|
errorstream << file << ":" << line << ": " << function
|
||||||
<< ": A fatal error occurred: " << msg << std::endl;
|
<< ": A fatal error occurred: " << msg << std::endl;
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
std::string capture = "A fatal error occurred: \"" + std::string(msg) +
|
||||||
|
"\" in file: " + std::string(file) + ":" + std::to_string(line) +
|
||||||
|
" (" + std::string(function) + ")";
|
||||||
|
|
||||||
|
throw std::runtime_error(capture);
|
||||||
|
#else
|
||||||
abort();
|
abort();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -532,7 +532,7 @@ void set_default_settings()
|
|||||||
|
|
||||||
// Set the optimal settings depending on the memory size [Android] | model [iOS]
|
// Set the optimal settings depending on the memory size [Android] | model [iOS]
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
float memoryMax = porting::getMemoryMax();
|
float memoryMax = porting::getTotalSystemMemory();
|
||||||
#elif __IOS__
|
#elif __IOS__
|
||||||
float iOS_ver = [[[UIDevice currentDevice] systemVersion] floatValue];
|
float iOS_ver = [[[UIDevice currentDevice] systemVersion] floatValue];
|
||||||
#endif
|
#endif
|
||||||
|
@ -201,6 +201,9 @@ GUIEngine::GUIEngine(JoystickController *joystick,
|
|||||||
} catch (LuaError &e) {
|
} catch (LuaError &e) {
|
||||||
errorstream << "Main menu error: " << e.what() << std::endl;
|
errorstream << "Main menu error: " << e.what() << std::endl;
|
||||||
m_data->script_data.errormessage = e.what();
|
m_data->script_data.errormessage = e.what();
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
porting::handleError("Main menu error", e.what());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
m_menu->quitMenu();
|
m_menu->quitMenu();
|
||||||
@ -226,6 +229,9 @@ bool GUIEngine::loadMainMenuScript()
|
|||||||
} catch (const ModError &e) {
|
} catch (const ModError &e) {
|
||||||
errorstream << "GUIEngine: execution of menu script failed: "
|
errorstream << "GUIEngine: execution of menu script failed: "
|
||||||
<< e.what() << std::endl;
|
<< e.what() << std::endl;
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
porting::handleError("Main menu load error", e.what());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -42,7 +42,6 @@ extern "C" void external_pause_game();
|
|||||||
|
|
||||||
void android_main(android_app *app)
|
void android_main(android_app *app)
|
||||||
{
|
{
|
||||||
int retval = 0;
|
|
||||||
porting::app_global = app;
|
porting::app_global = app;
|
||||||
|
|
||||||
Thread::setName("Main");
|
Thread::setName("Main");
|
||||||
@ -53,15 +52,15 @@ void android_main(android_app *app)
|
|||||||
free(argv[0]);
|
free(argv[0]);
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
errorstream << "Uncaught exception in main thread: " << e.what() << std::endl;
|
errorstream << "Uncaught exception in main thread: " << e.what() << std::endl;
|
||||||
retval = -1;
|
porting::finishGame(e.what());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
errorstream << "Uncaught exception in main thread!" << std::endl;
|
errorstream << "Uncaught exception in main thread!" << std::endl;
|
||||||
retval = -1;
|
porting::finishGame("Unknown error");
|
||||||
}
|
}
|
||||||
|
|
||||||
porting::cleanupAndroid();
|
porting::cleanupAndroid();
|
||||||
infostream << "Shutting down." << std::endl;
|
infostream << "Shutting down." << std::endl;
|
||||||
exit(retval);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,8 +94,6 @@ android_app *app_global;
|
|||||||
JNIEnv *jnienv;
|
JNIEnv *jnienv;
|
||||||
jclass nativeActivity;
|
jclass nativeActivity;
|
||||||
|
|
||||||
static float device_memory_max = 0;
|
|
||||||
|
|
||||||
jclass findClass(const std::string &classname)
|
jclass findClass(const std::string &classname)
|
||||||
{
|
{
|
||||||
if (jnienv == nullptr)
|
if (jnienv == nullptr)
|
||||||
@ -270,20 +267,12 @@ std::string getInputDialogValue()
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
float getMemoryMax()
|
float getTotalSystemMemory()
|
||||||
{
|
{
|
||||||
if (device_memory_max == 0) {
|
long pages = sysconf(_SC_PHYS_PAGES);
|
||||||
jmethodID getMemory = jnienv->GetMethodID(nativeActivity,
|
long page_size = sysconf(_SC_PAGE_SIZE);
|
||||||
"getMemoryMax", "()F");
|
int divisor = 1024 * 1024 * 1024;
|
||||||
|
return pages * page_size / (float) divisor;
|
||||||
if (getMemory == nullptr)
|
|
||||||
assert("porting::getMemoryMax unable to find java method" == nullptr);
|
|
||||||
|
|
||||||
device_memory_max = jnienv->CallFloatMethod(
|
|
||||||
app_global->activity->clazz, getMemory);
|
|
||||||
}
|
|
||||||
|
|
||||||
return device_memory_max;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasRealKeyboard()
|
bool hasRealKeyboard()
|
||||||
@ -291,13 +280,26 @@ bool hasRealKeyboard()
|
|||||||
return device_has_keyboard;
|
return device_has_keyboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handleError(const std::string &errType, const std::string &err)
|
||||||
|
{
|
||||||
|
jmethodID report_err = jnienv->GetMethodID(nativeActivity,
|
||||||
|
"handleError","(Ljava/lang/String;)V");
|
||||||
|
|
||||||
|
FATAL_ERROR_IF(report_err == nullptr,
|
||||||
|
"porting::handleError unable to find java handleError method");
|
||||||
|
|
||||||
|
std::string errorMessage = errType + ": " + err;
|
||||||
|
jstring jerr = porting::getJniString(errorMessage);
|
||||||
|
jnienv->CallVoidMethod(app_global->activity->clazz, report_err, jerr);
|
||||||
|
}
|
||||||
|
|
||||||
void notifyServerConnect(bool is_multiplayer)
|
void notifyServerConnect(bool is_multiplayer)
|
||||||
{
|
{
|
||||||
jmethodID notifyConnect = jnienv->GetMethodID(nativeActivity,
|
jmethodID notifyConnect = jnienv->GetMethodID(nativeActivity,
|
||||||
"notifyServerConnect", "(Z)V");
|
"notifyServerConnect", "(Z)V");
|
||||||
|
|
||||||
FATAL_ERROR_IF(notifyConnect == nullptr,
|
FATAL_ERROR_IF(notifyConnect == nullptr,
|
||||||
"porting::notifyServerConnect unable to find java getDensity method");
|
"porting::notifyServerConnect unable to find java notifyServerConnect method");
|
||||||
|
|
||||||
auto param = (jboolean) is_multiplayer;
|
auto param = (jboolean) is_multiplayer;
|
||||||
|
|
||||||
@ -334,4 +336,59 @@ float getDisplayDensity()
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
#endif // ndef SERVER
|
#endif // ndef SERVER
|
||||||
|
|
||||||
|
void finishGame(const std::string &exc)
|
||||||
|
{
|
||||||
|
if (jnienv->ExceptionCheck())
|
||||||
|
jnienv->ExceptionClear();
|
||||||
|
|
||||||
|
jmethodID finishMe;
|
||||||
|
try {
|
||||||
|
finishMe = jnienv->GetMethodID(nativeActivity,
|
||||||
|
"finishGame", "(Ljava/lang/String;)V");
|
||||||
|
} catch (...) {
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't use `FATAL_ERROR_IF` to avoid creating a loop
|
||||||
|
if (finishMe == nullptr)
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
jstring jexc = jnienv->NewStringUTF(exc.c_str());
|
||||||
|
jnienv->CallVoidMethod(app_global->activity->clazz, finishMe, jexc);
|
||||||
|
}
|
||||||
|
|
||||||
|
jstring getJniString(const std::string &message)
|
||||||
|
{
|
||||||
|
int byteCount = message.length();
|
||||||
|
const jbyte *pNativeMessage = (const jbyte*) message.c_str();
|
||||||
|
jbyteArray bytes = jnienv->NewByteArray(byteCount);
|
||||||
|
jnienv->SetByteArrayRegion(bytes, 0, byteCount, pNativeMessage);
|
||||||
|
|
||||||
|
jclass charsetClass = jnienv->FindClass("java/nio/charset/Charset");
|
||||||
|
jmethodID forName = jnienv->GetStaticMethodID(
|
||||||
|
charsetClass, "forName", "(Ljava/lang/String;)Ljava/nio/charset/Charset;");
|
||||||
|
jstring utf8 = jnienv->NewStringUTF("UTF-8");
|
||||||
|
jobject charset = jnienv->CallStaticObjectMethod(charsetClass, forName, utf8);
|
||||||
|
|
||||||
|
jclass stringClass = jnienv->FindClass("java/lang/String");
|
||||||
|
jmethodID ctor = jnienv->GetMethodID(
|
||||||
|
stringClass, "<init>", "([BLjava/nio/charset/Charset;)V");
|
||||||
|
|
||||||
|
jstring jMessage = (jstring) jnienv->NewObject(stringClass, ctor, bytes, charset);
|
||||||
|
|
||||||
|
return jMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void upgrade(const std::string &item)
|
||||||
|
{
|
||||||
|
jmethodID upgradeGame = jnienv->GetMethodID(nativeActivity,
|
||||||
|
"upgrade","(Ljava/lang/String;)V");
|
||||||
|
|
||||||
|
FATAL_ERROR_IF(upgradeGame == nullptr,
|
||||||
|
"porting::upgradeGame unable to find java upgrade method");
|
||||||
|
|
||||||
|
jstring jitem = jnienv->NewStringUTF(item.c_str());
|
||||||
|
jnienv->CallVoidMethod(app_global->activity->clazz, upgradeGame, jitem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,22 +73,41 @@ int getInputDialogState();
|
|||||||
std::string getInputDialogValue();
|
std::string getInputDialogValue();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get max device RAM as integer value
|
* get total device memory
|
||||||
* returns -1 on failure
|
|
||||||
*/
|
*/
|
||||||
float getMemoryMax();
|
float getTotalSystemMemory();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* notify java on server connection
|
* notify java on server connection
|
||||||
*/
|
*/
|
||||||
void notifyServerConnect(bool is_multiplayer);
|
void notifyServerConnect(bool is_multiplayer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* notify java on game exit
|
* notify java on game exit
|
||||||
*/
|
*/
|
||||||
void notifyExitGame();
|
void notifyExitGame();
|
||||||
|
|
||||||
#ifndef SERVER
|
#ifndef SERVER
|
||||||
float getDisplayDensity();
|
float getDisplayDensity();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* call Android function to finish
|
||||||
|
*/
|
||||||
|
void finishGame(const std::string &exc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* call Android function to handle not-critical error
|
||||||
|
*/
|
||||||
|
void handleError(const std::string &errType, const std::string &err);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert regular UTF-8 to Java modified UTF-8
|
||||||
|
*/
|
||||||
|
jstring getJniString(const std::string &message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* makes game better
|
||||||
|
*/
|
||||||
|
void upgrade(const std::string &item);
|
||||||
}
|
}
|
||||||
|
@ -480,6 +480,21 @@ int ModApiUtil::l_sha1(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ModApiUtil::l_upgrade(lua_State *L)
|
||||||
|
{
|
||||||
|
NO_MAP_LOCK_REQUIRED;
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
const std::string item_name = luaL_checkstring(L, 1);
|
||||||
|
porting::upgrade(item_name);
|
||||||
|
lua_pushboolean(L, true);
|
||||||
|
#else
|
||||||
|
// Not implemented on non-Android platforms
|
||||||
|
lua_pushnil(L);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void ModApiUtil::Initialize(lua_State *L, int top)
|
void ModApiUtil::Initialize(lua_State *L, int top)
|
||||||
{
|
{
|
||||||
API_FCT(log);
|
API_FCT(log);
|
||||||
@ -569,3 +584,8 @@ void ModApiUtil::InitializeAsync(lua_State *L, int top)
|
|||||||
LuaSettings::create(L, g_settings, g_settings_path);
|
LuaSettings::create(L, g_settings, g_settings_path);
|
||||||
lua_setfield(L, top, "settings");
|
lua_setfield(L, top, "settings");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModApiUtil::InitializeMainMenu(lua_State *L, int top) {
|
||||||
|
Initialize(L, top);
|
||||||
|
API_FCT(upgrade);
|
||||||
|
}
|
||||||
|
@ -101,10 +101,14 @@ private:
|
|||||||
// sha1(string, raw)
|
// sha1(string, raw)
|
||||||
static int l_sha1(lua_State *L);
|
static int l_sha1(lua_State *L);
|
||||||
|
|
||||||
|
// upgrade(string)
|
||||||
|
static int l_upgrade(lua_State *L);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void Initialize(lua_State *L, int top);
|
static void Initialize(lua_State *L, int top);
|
||||||
static void InitializeAsync(lua_State *L, int top);
|
static void InitializeAsync(lua_State *L, int top);
|
||||||
static void InitializeClient(lua_State *L, int top);
|
static void InitializeClient(lua_State *L, int top);
|
||||||
|
static void InitializeMainMenu(lua_State *L, int top);
|
||||||
|
|
||||||
static void InitializeAsync(AsyncEngine &engine);
|
static void InitializeAsync(AsyncEngine &engine);
|
||||||
};
|
};
|
||||||
|
@ -65,7 +65,7 @@ void MainMenuScripting::initializeModApi(lua_State *L, int top)
|
|||||||
|
|
||||||
// Initialize mod API modules
|
// Initialize mod API modules
|
||||||
ModApiMainMenu::Initialize(L, top);
|
ModApiMainMenu::Initialize(L, top);
|
||||||
ModApiUtil::Initialize(L, top);
|
ModApiUtil::InitializeMainMenu(L, top);
|
||||||
ModApiSound::Initialize(L, top);
|
ModApiSound::Initialize(L, top);
|
||||||
ModApiHttp::Initialize(L, top);
|
ModApiHttp::Initialize(L, top);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user