diff --git a/.gitignore b/.gitignore
index 9e166f4e..537f08f0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -123,7 +123,6 @@ Thumbs.db
!/ios-moe/xcode/*.xcodeproj/xcshareddata
!/ios-moe/xcode/*.xcodeproj/project.pbxproj
/ios-moe/xcode/native/
-gradle.properties
SaveFiles/
android/android-release.apk
android/assets/GameSettings.json
diff --git a/android/assets/jsons/translationsByLanguage/German.properties b/android/assets/jsons/translationsByLanguage/German.properties
index a4051e5f..29dcb8e8 100644
--- a/android/assets/jsons/translationsByLanguage/German.properties
+++ b/android/assets/jsons/translationsByLanguage/German.properties
@@ -1747,15 +1747,6 @@ Haka War Dance = Haka-Kriegstanz
Rejuvenation = Verjüngung
All healing effects doubled = Alle Heilungseffekte verdoppelt
# Multiplayer Turn Checker Service
-An error has occured = Ein Fehler ist aufgetreten
-Multiplayer turn notifier service terminated = Multiplayer Zug Benachrichtigungsdienst wurde beendet
-Your friends are waiting on your turn. = Deine Freunde warten auf deinen Zug.
-Unciv - It's your turn! = Unciv - Du bist am Zug!
-Unciv will inform you when it's your turn in multiplayer. = Unciv wird dich benachrichtigen, wenn du im Multiplayer am Zug bist.
-Last online turn check: [lastTimeChecked] = Letzter online Zug Check: [lastTimeChecked]
-Checks ca. every [checkPeriod] minute(s) when Internet available. = Prüft etwa alle [checkPeriod] Minute(n) wenn Internet vorhanden.
-Configurable in Unciv options menu. = Konfigurierbar im Unciv Optionsmenü.
-Unciv multiplayer turn notifier running = Unciv Multiplayer Zug Benachrichtiger läuft.
Multiplayer options = Multiplayer Einstellungen
Enable out-of-game turn notifications = Aktiviere Zug Benachrichtigungen außerhalb des Spiels
Time between turn checks out-of-game (in minutes) = Intervall zwischen Zug Prüfungen (in Minuten)
diff --git a/android/assets/jsons/translationsByLanguage/template.properties b/android/assets/jsons/translationsByLanguage/template.properties
index 3a2b15e2..d48a9ecd 100644
--- a/android/assets/jsons/translationsByLanguage/template.properties
+++ b/android/assets/jsons/translationsByLanguage/template.properties
@@ -1743,15 +1743,6 @@ Haka War Dance =
Rejuvenation =
All healing effects doubled =
# Multiplayer Turn Checker Service
-An error has occured =
-Multiplayer turn notifier service terminated =
-Your friends are waiting on your turn. =
-Unciv - It's your turn! =
-Unciv will inform you when it's your turn in multiplayer. =
-Last online turn check: [lastTimeChecked] =
-Checks ca. every [checkPeriod] minute(s) when Internet available. =
-Configurable in Unciv options menu. =
-Unciv multiplayer turn notifier running =
Multiplayer options =
Enable out-of-game turn notifications =
Time between turn checks out-of-game (in minutes) =
diff --git a/android/build.gradle b/android/build.gradle
index 1ef8549d..1719f7c1 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -62,6 +62,9 @@ android {
}
}
}
+ lintOptions {
+ disable 'MissingTranslation'
+ }
}
@@ -123,7 +126,7 @@ task run(type: Exec) {
dependencies {
implementation 'androidx.core:core:1.2.0'
- implementation "androidx.work:work-runtime-ktx:2.3.1"
+ implementation "androidx.work:work-runtime-ktx:2.3.2"
}
// sets up the Android Eclipse project, using the old Ant based build.
diff --git a/android/gradle.properties b/android/gradle.properties
new file mode 100644
index 00000000..d015431a
--- /dev/null
+++ b/android/gradle.properties
@@ -0,0 +1,2 @@
+android.useAndroidX=true
+android.enableJetifier=true
\ No newline at end of file
diff --git a/android/res/values-de/strings.xml b/android/res/values-de/strings.xml
new file mode 100644
index 00000000..e4c170cc
--- /dev/null
+++ b/android/res/values-de/strings.xml
@@ -0,0 +1,17 @@
+
+
+ UnCiv
+ Unciv - Du bist am Zug!
+ Deine Freunde warten auf deinen Zug.
+ Ein Fehler ist aufgetreten
+ Multiplayer Zug Benachrichtigungsdienst wurde beendet
+ Letzter online Zug Check:
+ Unciv wird dich benachrichtigen, wenn du im Multiplayer am Zug bist.
+ Prüft etwa alle
+ Minute(n) wenn Internet vorhanden.
+ Konfigurierbar im Unciv Optionsmenü.
+ Unciv Multiplayer Zugprüfer Ereignis
+ Informiert dich, wenn du im Multiplayer am Zug bist.
+ Unciv Multiplayer Zugprüfer Persistenter Status
+ Permanent angezeigte Benachrichtigung, welche dich über die Hintergrundaktivität des Dienstes informiert.
+
\ No newline at end of file
diff --git a/android/res/values-fr-rFR/strings.xml b/android/res/values-fr-rFR/strings.xml
new file mode 100644
index 00000000..d8567e77
--- /dev/null
+++ b/android/res/values-fr-rFR/strings.xml
@@ -0,0 +1,9 @@
+
+
+ UnCiv
+ Unciv - C\'est à vous !
+ Vos amis attendent votre action.
+ Service de notification du tour multijoueur terminé
+ Une erreur est survenue
+ Configurable dans le menu des options de Unciv
+
\ No newline at end of file
diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml
index db54450e..b5b5a4ef 100644
--- a/android/res/values/strings.xml
+++ b/android/res/values/strings.xml
@@ -1,4 +1,17 @@
UnCiv
+ Unciv - It\'s your turn!
+ Your friends are waiting on your turn.
+ An error has occurred
+ Multiplayer turn notifier service terminated
+ Last online turn check:
+ Unciv will inform you when it\'s your turn in multiplayer.
+ Checks ca. every
+ minute(s) when Internet available.
+ Configurable in Unciv options menu.
+ Unciv Multiplayer Turn Checker Alert
+ Informs you when it\'s your turn in multiplayer.
+ Unciv Multiplayer Turn Checker Persistent Status
+ Shown constantly to inform you about background checking.
diff --git a/android/src/com/unciv/app/MultiplayerTurnCheckWorker.kt b/android/src/com/unciv/app/MultiplayerTurnCheckWorker.kt
index 2f2162f0..925736e9 100644
--- a/android/src/com/unciv/app/MultiplayerTurnCheckWorker.kt
+++ b/android/src/com/unciv/app/MultiplayerTurnCheckWorker.kt
@@ -10,12 +10,10 @@ import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat.DEFAULT_VIBRATE
import androidx.core.app.NotificationManagerCompat
-import androidx.core.content.ContextCompat.getSystemService
import androidx.work.*
import com.badlogic.gdx.backends.android.AndroidApplication
import com.unciv.logic.GameInfo
import com.unciv.models.metadata.GameSettings
-import com.unciv.models.translations.tr
import com.unciv.ui.worldscreen.mainmenu.OnlineMultiplayer
import java.util.*
import java.util.concurrent.TimeUnit
@@ -37,16 +35,15 @@ class MultiplayerTurnCheckWorker(appContext: Context, workerParams: WorkerParame
private const val NOTIFICATION_CHANNEL_ID_INFO = "UNCIV_NOTIFICATION_CHANNEL_INFO"
private const val NOTIFICATION_CHANNEL_ID_SERVICE = "UNCIV_NOTIFICATION_CHANNEL_SERVICE_02"
+ private const val FAIL_COUNT = "FAIL_COUNT"
+ private const val GAME_ID = "GAME_ID"
+ private const val USER_ID = "USER_ID"
+ private const val CONFIGURED_DELAY = "CONFIGURED_DELAY"
+ private const val PERSISTENT_NOTIFICATION_ENABLED = "PERSISTENT_NOTIFICATION_ENABLED"
- // These fields need to be volatile because they are set by main thread but later accessed by worker thread.
- // Classes used here need to be primitive or internally synchronized to avoid visibility issues.
- @Volatile private var failCount = 0
- @Volatile private var gameId = ""
- @Volatile private var userId = ""
- @Volatile private var configuredDelay = 5
- @Volatile private var persistentNotificationEnabled = true
+ fun enqueue(appContext: Context,
+ delayInMinutes: Int, inputData: Data) {
- fun enqueue(appContext: Context, delayInMinutes: Int) {
val constraints = Constraints.Builder()
// If no internet is available, worker waits before becoming active.
.setRequiredNetworkType(NetworkType.CONNECTED)
@@ -56,6 +53,7 @@ class MultiplayerTurnCheckWorker(appContext: Context, workerParams: WorkerParame
.setConstraints(constraints)
.setInitialDelay(delayInMinutes.toLong(), TimeUnit.MINUTES)
.addTag(WORK_TAG)
+ .setInputData(inputData)
.build()
WorkManager.getInstance(appContext).enqueue(checkTurnWork)
@@ -70,8 +68,8 @@ class MultiplayerTurnCheckWorker(appContext: Context, workerParams: WorkerParame
*/
fun createNotificationChannelInfo(appContext: Context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- val name = "Unciv Multiplayer Turn Checker Alert"
- val descriptionText = "Informs you when it's your turn in multiplayer."
+ val name = appContext.resources.getString(R.string.Notify_ChannelInfo_Short)
+ val descriptionText = appContext.resources.getString(R.string.Notify_ChannelInfo_Long)
val importance = NotificationManager.IMPORTANCE_HIGH
val mChannel = NotificationChannel(NOTIFICATION_CHANNEL_ID_INFO, name, importance)
mChannel.description = descriptionText
@@ -92,8 +90,8 @@ class MultiplayerTurnCheckWorker(appContext: Context, workerParams: WorkerParame
*/
fun createNotificationChannelService(appContext: Context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- val name = "Unciv Multiplayer Turn Checker Persistent Status"
- val descriptionText = "Shown constantly to inform you about background checking."
+ val name = appContext.resources.getString(R.string.Notify_ChannelService_Short)
+ val descriptionText = appContext.resources.getString(R.string.Notify_ChannelService_Long)
val importance = NotificationManager.IMPORTANCE_MIN
val mChannel = NotificationChannel(NOTIFICATION_CHANNEL_ID_SERVICE, name, importance)
mChannel.setShowBadge(false)
@@ -110,29 +108,28 @@ class MultiplayerTurnCheckWorker(appContext: Context, workerParams: WorkerParame
* It is not technically necessary for the Worker, since it is not a Service.
*/
fun showPersistentNotification(appContext: Context, lastTimeChecked: String, checkPeriod: String) {
- if (persistentNotificationEnabled) {
- val pendingIntent: PendingIntent =
- Intent(appContext, AndroidLauncher::class.java).let { notificationIntent ->
- PendingIntent.getActivity(appContext, 0, notificationIntent, 0)
- }
+ val pendingIntent: PendingIntent =
+ Intent(appContext, AndroidLauncher::class.java).let { notificationIntent ->
+ PendingIntent.getActivity(appContext, 0, notificationIntent, 0)
+ }
- val notification: NotificationCompat.Builder = NotificationCompat.Builder(appContext, NOTIFICATION_CHANNEL_ID_SERVICE)
- .setPriority(NotificationManagerCompat.IMPORTANCE_MIN) // it's only a status
- .setContentTitle(("Last online turn check: [$lastTimeChecked]").tr())
- .setStyle(NotificationCompat.BigTextStyle()
- .bigText("Unciv will inform you when it's your turn in multiplayer.".tr() + " " +
- "Checks ca. every [$checkPeriod] minute(s) when Internet available.".tr()
- + " " + "Configurable in Unciv options menu.".tr()))
- .setSmallIcon(R.drawable.uncivicon2)
- .setContentIntent(pendingIntent)
- .setCategory(NotificationCompat.CATEGORY_SERVICE)
- .setOnlyAlertOnce(true)
- .setOngoing(true)
- .setShowWhen(false)
+ val notification: NotificationCompat.Builder = NotificationCompat.Builder(appContext, NOTIFICATION_CHANNEL_ID_SERVICE)
+ .setPriority(NotificationManagerCompat.IMPORTANCE_MIN) // it's only a status
+ .setContentTitle(appContext.resources.getString(R.string.Notify_Persist_Short) + " " + lastTimeChecked)
+ .setStyle(NotificationCompat.BigTextStyle()
+ .bigText(appContext.resources.getString(R.string.Notify_Persist_Long_P1) + " " +
+ appContext.resources.getString(R.string.Notify_Persist_Long_P2) + " " + checkPeriod + " "
+ + appContext.resources.getString(R.string.Notify_Persist_Long_P3)
+ + " " + appContext.resources.getString(R.string.Notify_Persist_Long_P4)))
+ .setSmallIcon(R.drawable.uncivicon2)
+ .setContentIntent(pendingIntent)
+ .setCategory(NotificationCompat.CATEGORY_SERVICE)
+ .setOnlyAlertOnce(true)
+ .setOngoing(true)
+ .setShowWhen(false)
- with(NotificationManagerCompat.from(appContext)) {
- notify(NOTIFICATION_ID_INFO, notification.build())
- }
+ with(NotificationManagerCompat.from(appContext)) {
+ notify(NOTIFICATION_ID_INFO, notification.build())
}
}
@@ -142,11 +139,11 @@ class MultiplayerTurnCheckWorker(appContext: Context, workerParams: WorkerParame
PendingIntent.getActivity(applicationContext, 0, notificationIntent, 0)
}
- val contentTitle = "Unciv - It's your turn!".tr()
+ val contentTitle = applicationContext.resources.getString(R.string.Notify_YourTurn_Short)
val notification: NotificationCompat.Builder = NotificationCompat.Builder(applicationContext, NOTIFICATION_CHANNEL_ID_INFO)
.setPriority(NotificationManagerCompat.IMPORTANCE_HIGH) // people are waiting!
.setContentTitle(contentTitle)
- .setContentText("Your friends are waiting on your turn.".tr())
+ .setContentText(applicationContext.resources.getString(R.string.Notify_YourTurn_Long))
.setTicker(contentTitle)
// without at least vibrate, some Android versions don't show a heads-up notification
.setDefaults(DEFAULT_VIBRATE)
@@ -166,15 +163,16 @@ class MultiplayerTurnCheckWorker(appContext: Context, workerParams: WorkerParame
// May be useful to remind a player that he forgot to complete his turn.
notifyUserAboutTurn(applicationContext)
} else {
- gameId = gameInfo.gameId
- userId = settings.userId
- configuredDelay = settings.multiplayerTurnCheckerDelayInMinutes
- persistentNotificationEnabled = settings.multiplayerTurnCheckerPersistentNotificationEnabled
+ val inputData = workDataOf(Pair(FAIL_COUNT, 0), Pair(GAME_ID, gameInfo.gameId),
+ Pair(USER_ID, settings.userId), Pair(CONFIGURED_DELAY, settings.multiplayerTurnCheckerDelayInMinutes),
+ Pair(PERSISTENT_NOTIFICATION_ENABLED, settings.multiplayerTurnCheckerPersistentNotificationEnabled))
- showPersistentNotification(applicationContext,
- "—", settings.multiplayerTurnCheckerDelayInMinutes.toString())
+ if (settings.multiplayerTurnCheckerPersistentNotificationEnabled) {
+ showPersistentNotification(applicationContext,
+ "—", settings.multiplayerTurnCheckerDelayInMinutes.toString())
+ }
// Initial check always happens after a minute, ignoring delay config. Better user experience this way.
- enqueue(applicationContext, 1)
+ enqueue(applicationContext, 1, inputData)
}
}
@@ -205,47 +203,51 @@ class MultiplayerTurnCheckWorker(appContext: Context, workerParams: WorkerParame
override fun doWork(): Result {
try {
- val latestGame = OnlineMultiplayer().tryDownloadGame(gameId)
- if (latestGame.currentPlayerCiv.playerId == userId) {
+ val latestGame = OnlineMultiplayer().tryDownloadGame(inputData.getString(GAME_ID)!!)
+ if (latestGame.currentPlayerCiv.playerId == inputData.getString(USER_ID)!!) {
notifyUserAboutTurn(applicationContext)
with(NotificationManagerCompat.from(applicationContext)) {
cancel(NOTIFICATION_ID_SERVICE)
}
} else {
- enqueue(applicationContext, configuredDelay)
- updatePersistentNotification()
+ updatePersistentNotification(inputData)
+ // We have to reset the fail counter since no exception appeared
+ val inputDataFailReset = Data.Builder().putAll(inputData).putInt(FAIL_COUNT, 0).build()
+ enqueue(applicationContext, inputData.getInt(CONFIGURED_DELAY, 5), inputDataFailReset)
}
- failCount = 0
} catch (ex: Exception) {
- if (failCount++ > 3) {
+ val failCount = inputData.getInt(FAIL_COUNT, 0)
+ if (failCount > 3) {
showErrorNotification()
with(NotificationManagerCompat.from(applicationContext)) {
cancel(NOTIFICATION_ID_SERVICE)
}
- failCount = 0 // Otherwise the notification service would be forever stuck in error mode.
return Result.failure()
} else {
// If check fails, retry in one minute.
// Makes sense, since checks only happen if Internet is available in principle.
// Therefore a failure means either a problem with the GameInfo or with Dropbox.
- enqueue(applicationContext, 1)
- updatePersistentNotification()
+ val inputDataFailIncrease = Data.Builder().putAll(inputData).putInt(FAIL_COUNT, failCount + 1).build()
+ enqueue(applicationContext, 1, inputDataFailIncrease)
+ // Persistent Notification is not updated, because user may think check succeed.
}
}
return Result.success()
}
- private fun updatePersistentNotification() {
- val cal = GregorianCalendar.getInstance()
- val hour = cal.get(GregorianCalendar.HOUR_OF_DAY).toString()
- var minute = cal.get(GregorianCalendar.MINUTE).toString()
- if (minute.length == 1) {
- minute = "0$minute"
- }
- val displayTime = "$hour:$minute"
+ private fun updatePersistentNotification(inputData: Data) {
+ if (inputData.getBoolean(PERSISTENT_NOTIFICATION_ENABLED, true)) {
+ val cal = GregorianCalendar.getInstance()
+ val hour = cal.get(GregorianCalendar.HOUR_OF_DAY).toString()
+ var minute = cal.get(GregorianCalendar.MINUTE).toString()
+ if (minute.length == 1) {
+ minute = "0$minute"
+ }
+ val displayTime = "$hour:$minute"
- showPersistentNotification(applicationContext, displayTime,
- configuredDelay.toString())
+ showPersistentNotification(applicationContext, displayTime,
+ inputData.getInt(CONFIGURED_DELAY, 5).toString())
+ }
}
private fun showErrorNotification() {
@@ -256,8 +258,8 @@ class MultiplayerTurnCheckWorker(appContext: Context, workerParams: WorkerParame
val notification: NotificationCompat.Builder = NotificationCompat.Builder(applicationContext, NOTIFICATION_CHANNEL_ID_INFO)
.setPriority(NotificationManagerCompat.IMPORTANCE_DEFAULT) // No direct user action expected
- .setContentTitle("An error has occured".tr())
- .setContentText("Multiplayer turn notifier service terminated".tr())
+ .setContentTitle(applicationContext.resources.getString(R.string.Notify_Error_Short))
+ .setContentText(applicationContext.resources.getString(R.string.Notify_Error_Long))
.setSmallIcon(R.drawable.uncivicon2)
// without at least vibrate, some Android versions don't show a heads-up notification
.setDefaults(DEFAULT_VIBRATE)
diff --git a/build.gradle b/build.gradle
index 797574f0..eed64dc6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,6 @@
buildscript {
- ext.kotlinVersion = '1.3.50'
+ ext.kotlinVersion = '1.3.61'
repositories {
// Chinese mirrors for quicker loading for chinese devs - uncomment if you're chinese
@@ -18,7 +18,7 @@ buildscript {
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.6'
- classpath 'com.android.tools.build:gradle:3.5.3'
+ classpath 'com.android.tools.build:gradle:3.6.0'
classpath 'com.mobidevelop.robovm:robovm-gradle-plugin:2.3.1'
// This is for wrapping the .jar file into a standalone executable
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 56e0614b..92a5f55b 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Sat Aug 24 11:02:13 CST 2019
+#Thu Feb 27 10:30:48 CET 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip