Added checksum to be added to uploaded multiplayer games (#9483)

* Added checksum to be added to uploaded multiplayer games

* Policy adoption triggers resource recalculation
This commit is contained in:
Yair Morgenstern
2023-05-31 14:58:00 +03:00
committed by GitHub
parent de09eda043
commit ce6d3394bc
5 changed files with 25 additions and 7 deletions

View File

@ -3,6 +3,7 @@ package com.unciv.logic
import com.unciv.Constants
import com.unciv.UncivGame
import com.unciv.UncivGame.Version
import com.unciv.json.json
import com.unciv.logic.BackwardCompatibility.convertEncampmentData
import com.unciv.logic.BackwardCompatibility.convertFortify
import com.unciv.logic.BackwardCompatibility.guaranteeUnitPromotions
@ -35,9 +36,11 @@ import com.unciv.models.ruleset.nation.Difficulty
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.ui.audio.MusicMood
import com.unciv.ui.audio.MusicTrackChooserFlags
import com.unciv.ui.screens.savescreens.Gzip
import com.unciv.ui.screens.worldscreen.status.NextTurnProgress
import com.unciv.utils.DebugUtils
import com.unciv.utils.debug
import java.security.MessageDigest
import java.util.UUID
@ -100,6 +103,7 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion
var currentPlayer = ""
var currentTurnStartTime = 0L
var gameId = UUID.randomUUID().toString() // random string
var checksum = ""
var victoryData:VictoryData? = null
@ -272,6 +276,16 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion
return year.toInt()
}
fun calculateChecksum():String {
val oldChecksum = checksum
checksum = "" // Checksum calculation cannot include old checksum, obvs
val bytes = MessageDigest
.getInstance("SHA-1")
.digest(json().toJson(this).toByteArray())
checksum = oldChecksum
return Gzip.encode(bytes)
}
//endregion
//region State changing functions

View File

@ -211,6 +211,8 @@ class PolicyManager : IsPartOfGameInfoSerialization {
if (unique.conditionals.any {it.type == UniqueType.TriggerUponAdoptingPolicyOrBelief && it.params[0] == policy.name})
UniqueTriggerActivation.triggerCivwideUnique(unique, civInfo, triggerNotificationText = triggerNotificationText)
civInfo.cache.updateCivResources()
// This ALSO has the side-effect of updating the CivInfo statForNextTurn so we don't need to call it explicitly
for (cityInfo in civInfo.cities) cityInfo.cityStats.update()

View File

@ -18,8 +18,8 @@ import com.unciv.models.metadata.GameSettings
import com.unciv.models.metadata.doMigrations
import com.unciv.models.metadata.isMigrationNecessary
import com.unciv.ui.screens.savescreens.Gzip
import com.unciv.utils.Log
import com.unciv.utils.Concurrency
import com.unciv.utils.Log
import com.unciv.utils.debug
import kotlinx.coroutines.Job
import java.io.File
@ -371,8 +371,10 @@ class UncivFiles(
}
/** Returns gzipped serialization of [game], optionally gzipped ([forceZip] overrides [saveZipped]) */
fun gameInfoToString(game: GameInfo, forceZip: Boolean? = null): String {
fun gameInfoToString(game: GameInfo, forceZip: Boolean? = null, updateChecksum:Boolean=true): String {
game.version = GameInfo.CURRENT_COMPATIBILITY_VERSION
if (updateChecksum) game.checksum = game.calculateChecksum()
val plainJson = json().toJson(game)
return if (forceZip ?: saveZipped) Gzip.zip(plainJson) else plainJson
}

View File

@ -102,7 +102,7 @@ class OnlineMultiplayerServer(
* @throws MultiplayerAuthException if the authentication failed
*/
suspend fun tryUploadGame(gameInfo: GameInfo, withPreview: Boolean) {
val zippedGameInfo = UncivFiles.gameInfoToString(gameInfo, forceZip = true)
val zippedGameInfo = UncivFiles.gameInfoToString(gameInfo, forceZip = true, updateChecksum = true)
fileStorage().saveFileData(gameInfo.gameId, zippedGameInfo)
// We upload the preview after the game because otherwise the following race condition will happen:

View File

@ -10,8 +10,8 @@ import java.util.zip.GZIPOutputStream
object Gzip {
fun zip(data:String):String = encoder(compress(data))
fun unzip(data:String):String = decompress(decoder(data))
fun zip(data:String):String = encode(compress(data))
fun unzip(data:String):String = decompress(decode(data))
private fun compress(data: String): ByteArray {
val bos = ByteArrayOutputStream(data.length)
@ -40,11 +40,11 @@ object Gzip {
}
private fun encoder(bytes:ByteArray): String{
fun encode(bytes:ByteArray): String{
return String(Base64Coder.encode(bytes))
}
private fun decoder(base64Str: String): ByteArray{
private fun decode(base64Str: String): ByteArray{
return Base64Coder.decode(base64Str)
}
}