diff --git a/core/src/com/unciv/UnCivGame.kt b/core/src/com/unciv/UnCivGame.kt index cee90552..98dfcba9 100644 --- a/core/src/com/unciv/UnCivGame.kt +++ b/core/src/com/unciv/UnCivGame.kt @@ -50,7 +50,7 @@ class UnCivGame(val version: String) : Game() { } fun loadGame(gameName:String){ - loadGame(GameSaver().loadGame(gameName)) + loadGame(GameSaver().loadGameByName(gameName)) } fun startNewGame() { diff --git a/core/src/com/unciv/logic/GameInfo.kt b/core/src/com/unciv/logic/GameInfo.kt index 1689cd38..0f30deb0 100644 --- a/core/src/com/unciv/logic/GameInfo.kt +++ b/core/src/com/unciv/logic/GameInfo.kt @@ -28,6 +28,7 @@ class GameInfo { var turns = 0 var oneMoreTurnMode=false var currentPlayer="" + var gameId = UUID.randomUUID().toString() // random string //region pure functions fun clone(): GameInfo { diff --git a/core/src/com/unciv/logic/GameSaver.kt b/core/src/com/unciv/logic/GameSaver.kt index 79048317..a616d953 100644 --- a/core/src/com/unciv/logic/GameSaver.kt +++ b/core/src/com/unciv/logic/GameSaver.kt @@ -25,12 +25,18 @@ class GameSaver { json().toJson(game,getSave(GameName)) } - fun loadGame(GameName: String) : GameInfo { + fun loadGameByName(GameName: String) : GameInfo { val game = json().fromJson(GameInfo::class.java, getSave(GameName)) game.setTransients() return game } + fun gameInfoFromString(gameData:String): GameInfo { + val game = json().fromJson(GameInfo::class.java, gameData) + game.setTransients() + return game + } + fun deleteSave(GameName: String){ getSave(GameName).delete() } diff --git a/core/src/com/unciv/ui/cityscreen/CityScreenCityPickerTable.kt b/core/src/com/unciv/ui/cityscreen/CityScreenCityPickerTable.kt index 79c4d512..22ef9ce2 100644 --- a/core/src/com/unciv/ui/cityscreen/CityScreenCityPickerTable.kt +++ b/core/src/com/unciv/ui/cityscreen/CityScreenCityPickerTable.kt @@ -45,7 +45,7 @@ class CityScreenCityPickerTable(val cityScreen: CityScreen) : Table(){ val textArea = TextField(city.name, CameraStageBaseScreen.skin) textArea.setAlignment(Align.center) editCityNamePopup.add(textArea).colspan(2).row() - editCityNamePopup.addButton("Close".tr()){editCityNamePopup.close()} + editCityNamePopup.addCloseButton() editCityNamePopup.addButton("Save".tr()){ city.name = textArea.text cityScreen.game.screen = CityScreen(city) diff --git a/core/src/com/unciv/ui/mapeditor/MapEditorOptionsTable.kt b/core/src/com/unciv/ui/mapeditor/MapEditorOptionsTable.kt index 41a79061..2b72bf31 100644 --- a/core/src/com/unciv/ui/mapeditor/MapEditorOptionsTable.kt +++ b/core/src/com/unciv/ui/mapeditor/MapEditorOptionsTable.kt @@ -72,14 +72,14 @@ class MapEditorOptionsTable(mapEditorScreen: MapEditorScreen): PopupTable(mapEdi remove() val uploadedSuccessfully = PopupTable(screen) uploadedSuccessfully.addGoodSizedLabel("Map uploaded successfully!").row() - uploadedSuccessfully.addButton("Close") { uploadedSuccessfully.remove() } + uploadedSuccessfully.addCloseButton() uploadedSuccessfully.open() } catch(ex:Exception){ remove() val couldNotUpload = PopupTable(screen) couldNotUpload.addGoodSizedLabel("Could not upload map!").row() - couldNotUpload.addButton("Close") { couldNotUpload.remove() } + couldNotUpload.addCloseButton() couldNotUpload.open() } } @@ -125,7 +125,7 @@ class MapDownloadTable(mapEditorScreen: MapEditorScreen):PopupTable(mapEditorScr } catch (ex: Exception) { addGoodSizedLabel("Could not get list of maps!").row() } - addButton("Close") { close() } + addCloseButton() open() } } \ No newline at end of file diff --git a/core/src/com/unciv/ui/newgamescreen/NewGameScreen.kt b/core/src/com/unciv/ui/newgamescreen/NewGameScreen.kt index ad06154e..2f26ba76 100644 --- a/core/src/com/unciv/ui/newgamescreen/NewGameScreen.kt +++ b/core/src/com/unciv/ui/newgamescreen/NewGameScreen.kt @@ -14,6 +14,7 @@ import com.unciv.ui.utils.disable import com.unciv.ui.utils.enable import com.unciv.ui.utils.onClick import com.unciv.ui.worldscreen.WorldScreen +import com.unciv.ui.worldscreen.optionstable.OnlineMultiplayer import com.unciv.ui.worldscreen.optionstable.PopupTable import java.util.* import kotlin.concurrent.thread @@ -37,20 +38,19 @@ class NewGameScreen: PickerScreen(){ if (newGameParameters.players.none { it.playerType == PlayerType.Human }) { val noHumanPlayersPopup = PopupTable(this) noHumanPlayersPopup.addGoodSizedLabel("No human players selected!").row() - noHumanPlayersPopup.addButton("Close") { noHumanPlayersPopup.close() } + noHumanPlayersPopup.addCloseButton() noHumanPlayersPopup.open() return@onClick } - if (newGameParameters.isOnlineMultiplayer){ - for(player in newGameParameters.players.filter{ it.playerType == PlayerType.Human}) { + if (newGameParameters.isOnlineMultiplayer) { + for (player in newGameParameters.players.filter { it.playerType == PlayerType.Human }) { try { UUID.fromString(player.playerId) - } - catch (ex:Exception) { + } catch (ex: Exception) { val invalidPlayerIdPopup = PopupTable(this) invalidPlayerIdPopup.addGoodSizedLabel("Invalid player ID!").row() - invalidPlayerIdPopup.addButton("Close") { invalidPlayerIdPopup.remove() } + invalidPlayerIdPopup.addCloseButton() invalidPlayerIdPopup.open() return@onClick } @@ -65,10 +65,21 @@ class NewGameScreen: PickerScreen(){ // Creating a new game can take a while and we don't want ANRs try { newGame = GameStarter().startNewGame(newGameParameters) + if (newGameParameters.isOnlineMultiplayer) { + try { + OnlineMultiplayer().tryUploadGame(newGame!!) + } catch (ex: Exception) { + val cantUploadNewGamePopup = PopupTable(this) + cantUploadNewGamePopup.addGoodSizedLabel("Can't upload the new game!") + cantUploadNewGamePopup.addCloseButton() + newGame = null + } + } } catch (exception: Exception) { val cantMakeThatMapPopup = PopupTable(this) cantMakeThatMapPopup.addGoodSizedLabel("It looks like we can't make a map with the parameters you requested!".tr()).row() cantMakeThatMapPopup.addGoodSizedLabel("Maybe you put too many players into too small a map?".tr()).row() + cantMakeThatMapPopup.addCloseButton() cantMakeThatMapPopup.open() } } diff --git a/core/src/com/unciv/ui/saves/LoadGameScreen.kt b/core/src/com/unciv/ui/saves/LoadGameScreen.kt index 06a49188..346cc2b3 100644 --- a/core/src/com/unciv/ui/saves/LoadGameScreen.kt +++ b/core/src/com/unciv/ui/saves/LoadGameScreen.kt @@ -9,7 +9,6 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.TextButton import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener import com.unciv.UnCivGame -import com.unciv.logic.GameInfo import com.unciv.logic.GameSaver import com.unciv.models.gamebasics.tr import com.unciv.ui.pickerscreens.PickerScreen @@ -61,8 +60,7 @@ class LoadGameScreen : PickerScreen() { try { val clipboardContentsString = Gdx.app.clipboard.contents.trim() val decoded = Gzip.unzip(clipboardContentsString) - val loadedGame = GameSaver().json().fromJson(GameInfo::class.java, decoded) - loadedGame.setTransients() + val loadedGame = GameSaver().gameInfoFromString(decoded) UnCivGame.Current.loadGame(loadedGame) } catch (ex: Exception) { errorLabel.setText("Could not load game from clipboard!".tr()) @@ -113,7 +111,7 @@ class LoadGameScreen : PickerScreen() { val savedAt = Date(GameSaver().getSave(save).lastModified()) textToSet += "\n{Saved at}: ".tr() + SimpleDateFormat("dd-MM-yy HH.mm").format(savedAt) try { - val game = GameSaver().loadGame(save) + val game = GameSaver().loadGameByName(save) val playerCivNames = game.civilizations.filter { it.isPlayerCivilization() }.joinToString { it.civName.tr() } textToSet += "\n" + playerCivNames + ", " + game.difficulty.tr() + ", {Turn} ".tr() + game.turns diff --git a/core/src/com/unciv/ui/worldscreen/AlertPopup.kt b/core/src/com/unciv/ui/worldscreen/AlertPopup.kt index da749812..0c24c049 100644 --- a/core/src/com/unciv/ui/worldscreen/AlertPopup.kt +++ b/core/src/com/unciv/ui/worldscreen/AlertPopup.kt @@ -80,7 +80,6 @@ class AlertPopup(val worldScreen: WorldScreen, val popupAlert: PopupAlert): Popu AlertType.DemandToStopSettlingCitiesNear -> { val otherciv= worldScreen.gameInfo.getCivilization(popupAlert.value) val playerDiploManager = worldScreen.viewingCiv.getDiplomacyManager(otherciv) - val translatedNation = otherciv.getTranslatedNation() addLeaderName(otherciv) addGoodSizedLabel("Please don't settle new cities near us.").row() add(getCloseButton("Very well, we shall look for new lands to settle."){ diff --git a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt index a5b8dbe0..8c2e8f31 100644 --- a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt +++ b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt @@ -26,6 +26,7 @@ import com.unciv.ui.trade.DiplomacyScreen import com.unciv.ui.utils.* import com.unciv.ui.worldscreen.bottombar.BattleTable import com.unciv.ui.worldscreen.bottombar.WorldScreenBottomBar +import com.unciv.ui.worldscreen.optionstable.OnlineMultiplayer import com.unciv.ui.worldscreen.optionstable.PopupTable import com.unciv.ui.worldscreen.unit.UnitActionsTable import kotlin.concurrent.thread @@ -101,15 +102,16 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() { update() - if(gameInfo.gameParameters.isOnlineMultiplayer && !gameInfo.isUpToDate){ + if(gameInfo.gameParameters.isOnlineMultiplayer && !gameInfo.isUpToDate) { val loadingGamePopup = PopupTable(this) loadingGamePopup.add("Loading latest game state...") loadingGamePopup.open() thread { - try{ - // todo!!! - } - catch (ex:Exception){ + try { + val latestGame = OnlineMultiplayer().tryDownloadGame(gameInfo.gameId) + latestGame.isUpToDate=true + game.loadGame(latestGame) + } catch (ex: Exception) { loadingGamePopup.close() } } diff --git a/core/src/com/unciv/ui/worldscreen/optionstable/DropBox.kt b/core/src/com/unciv/ui/worldscreen/optionstable/DropBox.kt index 490e0b6c..5bc2867c 100644 --- a/core/src/com/unciv/ui/worldscreen/optionstable/DropBox.kt +++ b/core/src/com/unciv/ui/worldscreen/optionstable/DropBox.kt @@ -1,6 +1,8 @@ package com.unciv.ui.worldscreen.optionstable +import com.unciv.logic.GameInfo import com.unciv.logic.GameSaver +import com.unciv.ui.saves.Gzip import java.io.BufferedReader import java.io.DataOutputStream import java.io.InputStreamReader @@ -10,13 +12,10 @@ import java.nio.charset.StandardCharsets class DropBox(){ - /** - * @param dropboxApiArg If true, then the data will be sent via a Dropbox-Api-Arg header and not via the post body - */ fun dropboxApi(url:String, data:String="",contentType:String="",dropboxApiArg:String=""):String { with(URL(url).openConnection() as HttpURLConnection) { - requestMethod = "POST" // optional default is GET + requestMethod = "POST" // default is GET setRequestProperty("Authorization", "Bearer LTdBbopPUQ0AAAAAAAACxh4_Qd1eVMM7IBK3ULV3BgxzWZDMfhmgFbuUNF_rXQWb") @@ -74,4 +73,18 @@ class DropBox(){ var path_display="" } +} + +class OnlineMultiplayer(){ + fun getGameLocation(gameId:String) = "/MultiplayerGames/$gameId" + + fun tryUploadGame(gameInfo: GameInfo){ + val zippedGameInfo = Gzip.zip(GameSaver().json().toJson(gameInfo)) + DropBox().uploadFile(getGameLocation(gameInfo.gameId),zippedGameInfo) + } + + fun tryDownloadGame(gameId: String): GameInfo { + val zippedGameInfo = DropBox().downloadFile(gameId) + return GameSaver().gameInfoFromString(Gzip.unzip(zippedGameInfo)) + } } \ No newline at end of file diff --git a/core/src/com/unciv/ui/worldscreen/optionstable/PopupTable.kt b/core/src/com/unciv/ui/worldscreen/optionstable/PopupTable.kt index dc7acc64..c907ca60 100644 --- a/core/src/com/unciv/ui/worldscreen/optionstable/PopupTable.kt +++ b/core/src/com/unciv/ui/worldscreen/optionstable/PopupTable.kt @@ -38,5 +38,7 @@ open class PopupTable(val screen: CameraStageBaseScreen): Table(CameraStageBaseS button.onClick(action) return add(button).apply { row() } } + + fun addCloseButton() = addButton("Close"){close()} } diff --git a/core/src/com/unciv/ui/worldscreen/optionstable/WorldScreenMenuTable.kt b/core/src/com/unciv/ui/worldscreen/optionstable/WorldScreenMenuTable.kt index af0f6030..1af17544 100644 --- a/core/src/com/unciv/ui/worldscreen/optionstable/WorldScreenMenuTable.kt +++ b/core/src/com/unciv/ui/worldscreen/optionstable/WorldScreenMenuTable.kt @@ -65,7 +65,7 @@ class WorldScreenMenuTable(val worldScreen: WorldScreen) : PopupTable(worldScree remove() } - addButton("Close".tr()){ close() } + addCloseButton() open() } @@ -83,7 +83,7 @@ class WorldScreenCommunityTable(val worldScreen: WorldScreen) : PopupTable(world remove() } - addButton("Close".tr()){ close() } + addCloseButton() open() } diff --git a/core/src/com/unciv/ui/worldscreen/optionstable/WorldScreenOptionsTable.kt b/core/src/com/unciv/ui/worldscreen/optionstable/WorldScreenOptionsTable.kt index 19b31522..ff5e990b 100644 --- a/core/src/com/unciv/ui/worldscreen/optionstable/WorldScreenOptionsTable.kt +++ b/core/src/com/unciv/ui/worldscreen/optionstable/WorldScreenOptionsTable.kt @@ -96,7 +96,7 @@ class WorldScreenOptionsTable(val worldScreen:WorldScreen) : PopupTable(worldScr scrollPane.setScrollingDisabled(true,false) add(scrollPane).maxHeight(screen.stage.height*0.6f).row() - addButton("Close"){ close() } + addCloseButton() pack() // Needed to show the background. center(UnCivGame.Current.worldScreen.stage)