Can now upload and download uploaded maps in the map editor screen!

This commit is contained in:
Yair Morgenstern 2019-08-01 21:38:09 +03:00
parent 9c1864708f
commit 23eb7d2f19
9 changed files with 108 additions and 48 deletions

View File

@ -4,28 +4,14 @@ import com.badlogic.gdx.Gdx
import com.badlogic.gdx.files.FileHandle import com.badlogic.gdx.files.FileHandle
import com.badlogic.gdx.utils.Json import com.badlogic.gdx.utils.Json
import com.unciv.GameSettings import com.unciv.GameSettings
import com.unciv.logic.map.TileMap
import com.unciv.ui.saves.Gzip
import com.unciv.ui.utils.ImageGetter import com.unciv.ui.utils.ImageGetter
import java.io.File import java.io.File
class GameSaver { class GameSaver {
private val saveFilesFolder = "SaveFiles" private val saveFilesFolder = "SaveFiles"
private val mapsFolder = "maps"
fun json() = Json().apply { setIgnoreDeprecated(true); ignoreUnknownFields = true } // Json() is NOT THREAD SAFE so we need to create a new one for each function fun json() = Json().apply { setIgnoreDeprecated(true); ignoreUnknownFields = true } // Json() is NOT THREAD SAFE so we need to create a new one for each function
fun getMap(mapName:String) = Gdx.files.local("$mapsFolder/$mapName")
fun saveMap(mapName: String,tileMap: TileMap){
getMap(mapName).writeString(Gzip.zip(json().toJson(tileMap)), false)
}
fun loadMap(mapName: String): TileMap {
val gzippedString = getMap(mapName).readString()
val unzippedJson = Gzip.unzip(gzippedString)
return json().fromJson(TileMap::class.java, unzippedJson)
}
fun getMaps() = Gdx.files.local(mapsFolder).list().map { it.name() }
fun getSave(GameName: String): FileHandle { fun getSave(GameName: String): FileHandle {
return Gdx.files.local("$saveFilesFolder/$GameName") return Gdx.files.local("$saveFilesFolder/$GameName")
@ -88,3 +74,4 @@ class GameSaver {
} }
} }

View File

@ -0,0 +1,25 @@
package com.unciv.logic
import com.badlogic.gdx.Gdx
import com.unciv.logic.map.TileMap
import com.unciv.ui.saves.Gzip
class MapSaver(){
fun json() = GameSaver().json()
private val mapsFolder = "maps"
fun getMap(mapName:String) = Gdx.files.local("$mapsFolder/$mapName")
fun saveMap(mapName: String,tileMap: TileMap){
getMap(mapName).writeString(Gzip.zip(json().toJson(tileMap)), false)
}
fun loadMap(mapName: String): TileMap {
val gzippedString = getMap(mapName).readString()
val unzippedJson = Gzip.unzip(gzippedString)
return json().fromJson(TileMap::class.java, unzippedJson)
}
fun getMaps() = Gdx.files.local(mapsFolder).list().map { it.name() }
fun mapFromJson(json:String): TileMap = json().fromJson(TileMap::class.java, json)
}

View File

@ -3,8 +3,8 @@ package com.unciv.logic.map
import com.badlogic.gdx.math.Vector2 import com.badlogic.gdx.math.Vector2
import com.unciv.GameParameters import com.unciv.GameParameters
import com.unciv.logic.GameInfo import com.unciv.logic.GameInfo
import com.unciv.logic.GameSaver
import com.unciv.logic.HexMath import com.unciv.logic.HexMath
import com.unciv.logic.MapSaver
import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.GameBasics
@ -36,7 +36,7 @@ class TileMap {
val mapValues:Collection<TileInfo> val mapValues:Collection<TileInfo>
if(newGameParameters.mapType == MapType.File) if(newGameParameters.mapType == MapType.File)
mapValues = GameSaver().loadMap(newGameParameters.mapFileName!!).values mapValues = MapSaver().loadMap(newGameParameters.mapFileName!!).values
else if(newGameParameters.mapType==MapType.Perlin) else if(newGameParameters.mapType==MapType.Perlin)
mapValues = PerlinNoiseRandomMapGenerator().generateMap(newGameParameters.mapRadius).values mapValues = PerlinNoiseRandomMapGenerator().generateMap(newGameParameters.mapRadius).values
else else

View File

@ -9,7 +9,7 @@ import com.unciv.GameSpeed
import com.unciv.GameStarter import com.unciv.GameStarter
import com.unciv.UnCivGame import com.unciv.UnCivGame
import com.unciv.logic.GameInfo import com.unciv.logic.GameInfo
import com.unciv.logic.GameSaver import com.unciv.logic.MapSaver
import com.unciv.logic.map.MapType import com.unciv.logic.map.MapType
import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.gamebasics.VictoryType import com.unciv.models.gamebasics.VictoryType
@ -121,7 +121,7 @@ class NewGameScreen: PickerScreen(){
newGameOptionsTable.add("{Map type}:".tr()) newGameOptionsTable.add("{Map type}:".tr())
val mapTypes = LinkedHashMap<String, MapType>() val mapTypes = LinkedHashMap<String, MapType>()
for (type in MapType.values()) { for (type in MapType.values()) {
if (type == MapType.File && GameSaver().getMaps().isEmpty()) continue if (type == MapType.File && MapSaver().getMaps().isEmpty()) continue
mapTypes[type.toString()] = type mapTypes[type.toString()] = type
} }
@ -273,7 +273,7 @@ class NewGameScreen: PickerScreen(){
private fun getMapFileSelectBox(): SelectBox<String> { private fun getMapFileSelectBox(): SelectBox<String> {
val mapFileSelectBox = SelectBox<String>(skin) val mapFileSelectBox = SelectBox<String>(skin)
val mapNames = Array<String>() val mapNames = Array<String>()
for (mapName in GameSaver().getMaps()) mapNames.add(mapName) for (mapName in MapSaver().getMaps()) mapNames.add(mapName)
mapFileSelectBox.items = mapNames mapFileSelectBox.items = mapNames
mapFileSelectBox.addListener(object : ChangeListener() { mapFileSelectBox.addListener(object : ChangeListener() {

View File

@ -6,11 +6,12 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextField
import com.badlogic.gdx.utils.Json import com.badlogic.gdx.utils.Json
import com.unciv.Constants import com.unciv.Constants
import com.unciv.UnCivGame import com.unciv.UnCivGame
import com.unciv.logic.GameSaver import com.unciv.logic.MapSaver
import com.unciv.logic.map.RoadStatus import com.unciv.logic.map.RoadStatus
import com.unciv.models.gamebasics.tr import com.unciv.models.gamebasics.tr
import com.unciv.ui.saves.Gzip import com.unciv.ui.saves.Gzip
import com.unciv.ui.utils.onClick import com.unciv.ui.utils.onClick
import com.unciv.ui.worldscreen.optionstable.DropBox
import com.unciv.ui.worldscreen.optionstable.PopupTable import com.unciv.ui.worldscreen.optionstable.PopupTable
class MapEditorOptionsTable(mapEditorScreen: MapEditorScreen): PopupTable(mapEditorScreen){ class MapEditorOptionsTable(mapEditorScreen: MapEditorScreen): PopupTable(mapEditorScreen){
@ -39,7 +40,7 @@ class MapEditorOptionsTable(mapEditorScreen: MapEditorScreen): PopupTable(mapEdi
val saveMapButton = TextButton("Save".tr(), skin) val saveMapButton = TextButton("Save".tr(), skin)
saveMapButton.onClick { saveMapButton.onClick {
GameSaver().saveMap(mapEditorScreen.mapName,mapEditorScreen.tileMap) MapSaver().saveMap(mapEditorScreen.mapName,mapEditorScreen.tileMap)
UnCivGame.Current.setWorldScreen() UnCivGame.Current.setWorldScreen()
} }
add(saveMapButton).row() add(saveMapButton).row()
@ -56,6 +57,17 @@ class MapEditorOptionsTable(mapEditorScreen: MapEditorScreen): PopupTable(mapEdi
loadMapButton.onClick { MapScreenLoadTable(mapEditorScreen); remove() } loadMapButton.onClick { MapScreenLoadTable(mapEditorScreen); remove() }
add(loadMapButton).row() add(loadMapButton).row()
val uploadMapButton = TextButton("Upload".tr(), skin)
uploadMapButton.onClick {
val gzippedMap = Gzip.zip(Json().toJson(mapEditorScreen.tileMap))
DropBox().uploadFile("/Maps/"+mapEditorScreen.mapName,gzippedMap)
}
add(uploadMapButton).row()
val downloadMapButton = TextButton("Download".tr(), skin)
downloadMapButton.onClick { MapDownloadTable(mapEditorScreen); remove() }
add(downloadMapButton).row()
val exitMapEditorButton = TextButton("Exit map editor".tr(), skin) val exitMapEditorButton = TextButton("Exit map editor".tr(), skin)
exitMapEditorButton.onClick { UnCivGame.Current.setWorldScreen(); mapEditorScreen.dispose() } exitMapEditorButton.onClick { UnCivGame.Current.setWorldScreen(); mapEditorScreen.dispose() }
add(exitMapEditorButton ).row() add(exitMapEditorButton ).row()
@ -64,6 +76,29 @@ class MapEditorOptionsTable(mapEditorScreen: MapEditorScreen): PopupTable(mapEdi
closeOptionsButtton.onClick { remove() } closeOptionsButtton.onClick { remove() }
add(closeOptionsButtton).row() add(closeOptionsButtton).row()
open()
}
}
class MapDownloadTable(mapEditorScreen: MapEditorScreen):PopupTable(mapEditorScreen){
init{
val folderList: DropBox.FolderList
try{
folderList = DropBox().getFolderList("/Maps")
for(downloadableMap in folderList.entries){
addButton(downloadableMap.name){
val mapJsonGzipped = DropBox().downloadFile(downloadableMap.path_display)
val decodedMapJson = Gzip.unzip(mapJsonGzipped)
val mapObject = MapSaver().mapFromJson(decodedMapJson)
MapSaver().saveMap(downloadableMap.name, mapObject)
UnCivGame.Current.screen = MapEditorScreen(mapObject)
}
}
}
catch (ex:Exception){
addGoodSizedLabel("Could not get list of maps!")
}
addButton("Close"){remove()}
open() open()
} }
} }

View File

@ -3,13 +3,14 @@ package com.unciv.ui.mapeditor
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane
import com.badlogic.gdx.scenes.scene2d.ui.TextButton import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.unciv.GameParameters import com.unciv.GameParameters
import com.unciv.logic.GameSaver import com.unciv.logic.MapSaver
import com.unciv.logic.map.TileMap import com.unciv.logic.map.TileMap
import com.unciv.models.gamebasics.tr import com.unciv.models.gamebasics.tr
import com.unciv.ui.tilegroups.TileGroup import com.unciv.ui.tilegroups.TileGroup
import com.unciv.ui.tilegroups.TileSetStrings import com.unciv.ui.tilegroups.TileSetStrings
import com.unciv.ui.utils.CameraStageBaseScreen import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.utils.onClick import com.unciv.ui.utils.onClick
import com.unciv.ui.utils.setFontSize
import com.unciv.ui.worldscreen.TileGroupMap import com.unciv.ui.worldscreen.TileGroupMap
class MapEditorScreen(): CameraStageBaseScreen(){ class MapEditorScreen(): CameraStageBaseScreen(){
@ -22,13 +23,13 @@ class MapEditorScreen(): CameraStageBaseScreen(){
constructor(mapNameToLoad:String?):this(){ constructor(mapNameToLoad:String?):this(){
var mapToLoad = mapNameToLoad var mapToLoad = mapNameToLoad
if (mapToLoad == null) { if (mapToLoad == null) {
val existingSaves = GameSaver().getMaps() val existingSaves = MapSaver().getMaps()
if(existingSaves.isNotEmpty()) if(existingSaves.isNotEmpty())
mapToLoad = existingSaves.first() mapToLoad = existingSaves.first()
} }
if(mapToLoad!=null){ if(mapToLoad!=null){
mapName=mapToLoad mapName=mapToLoad
tileMap=GameSaver().loadMap(mapName) tileMap= MapSaver().loadMap(mapName)
} }
initialize() initialize()
} }
@ -38,7 +39,7 @@ class MapEditorScreen(): CameraStageBaseScreen(){
initialize() initialize()
} }
fun initialize(){ fun initialize() {
tileMap.setTransients() tileMap.setTransients()
val mapHolder = getMapHolder(tileMap) val mapHolder = getMapHolder(tileMap)
@ -47,11 +48,17 @@ class MapEditorScreen(): CameraStageBaseScreen(){
stage.addActor(tileEditorOptions) stage.addActor(tileEditorOptions)
val saveMapButton = TextButton("Options".tr(),skin) val optionsMenuButton = TextButton("Options".tr(), skin)
saveMapButton.onClick { optionsMenuButton.onClick {
MapEditorOptionsTable(this) MapEditorOptionsTable(this)
} }
stage.addActor(saveMapButton) optionsMenuButton.label.setFontSize(24)
optionsMenuButton.labelCell.pad(20f)
optionsMenuButton.pack()
optionsMenuButton.x = 30f
optionsMenuButton.y = 30f
stage.addActor(optionsMenuButton)
} }
private fun getMapHolder(tileMap: TileMap): ScrollPane { private fun getMapHolder(tileMap: TileMap): ScrollPane {

View File

@ -4,10 +4,8 @@ import com.badlogic.gdx.Gdx
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox import com.badlogic.gdx.scenes.scene2d.ui.SelectBox
import com.badlogic.gdx.scenes.scene2d.ui.TextButton import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.badlogic.gdx.utils.Array import com.badlogic.gdx.utils.Array
import com.badlogic.gdx.utils.Json
import com.unciv.UnCivGame import com.unciv.UnCivGame
import com.unciv.logic.GameSaver import com.unciv.logic.MapSaver
import com.unciv.logic.map.TileMap
import com.unciv.models.gamebasics.tr import com.unciv.models.gamebasics.tr
import com.unciv.ui.saves.Gzip import com.unciv.ui.saves.Gzip
import com.unciv.ui.utils.CameraStageBaseScreen import com.unciv.ui.utils.CameraStageBaseScreen
@ -18,7 +16,7 @@ class MapScreenLoadTable(mapEditorScreen: MapEditorScreen): PopupTable(mapEditor
init{ init{
val mapFileSelectBox = SelectBox<String>(CameraStageBaseScreen.skin) val mapFileSelectBox = SelectBox<String>(CameraStageBaseScreen.skin)
val mapNames = Array<String>() val mapNames = Array<String>()
for (mapName in GameSaver().getMaps()) mapNames.add(mapName) for (mapName in MapSaver().getMaps()) mapNames.add(mapName)
mapFileSelectBox.items = mapNames mapFileSelectBox.items = mapNames
add(mapFileSelectBox).row() add(mapFileSelectBox).row()
@ -32,7 +30,7 @@ class MapScreenLoadTable(mapEditorScreen: MapEditorScreen): PopupTable(mapEditor
loadFromClipboardButton .onClick { loadFromClipboardButton .onClick {
val clipboardContentsString = Gdx.app.clipboard.contents.trim() val clipboardContentsString = Gdx.app.clipboard.contents.trim()
val decoded = Gzip.unzip(clipboardContentsString) val decoded = Gzip.unzip(clipboardContentsString)
val loadedMap = Json().fromJson(TileMap::class.java, decoded) val loadedMap = MapSaver().mapFromJson(decoded)
UnCivGame.Current.screen = MapEditorScreen(loadedMap) UnCivGame.Current.screen = MapEditorScreen(loadedMap)
} }
add(loadFromClipboardButton).row() add(loadFromClipboardButton).row()

View File

@ -13,18 +13,20 @@ class DropBox(){
/** /**
* @param dropboxApiArg If true, then the data will be sent via a Dropbox-Api-Arg header and not via the post body * @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="",dropboxApiArg:Boolean=false):String{ fun dropboxApi(url:String, data:String="",contentType:String="",dropboxApiArg:String=""):String {
with(URL(url).openConnection() as HttpURLConnection) { with(URL(url).openConnection() as HttpURLConnection) {
requestMethod = "POST" // optional default is GET requestMethod = "POST" // optional default is GET
setRequestProperty("Authorization","Bearer LTdBbopPUQ0AAAAAAAACxh4_Qd1eVMM7IBK3ULV3BgxzWZDMfhmgFbuUNF_rXQWb") setRequestProperty("Authorization", "Bearer LTdBbopPUQ0AAAAAAAACxh4_Qd1eVMM7IBK3ULV3BgxzWZDMfhmgFbuUNF_rXQWb")
if(!dropboxApiArg) setRequestProperty("Content-Type","application/json")
setRequestProperty("Dropbox-API-Arg", data) if (dropboxApiArg != "") setRequestProperty("Dropbox-API-Arg", dropboxApiArg)
if (contentType != "") setRequestProperty("Content-Type", contentType)
doOutput = true doOutput = true
try { try {
if(!dropboxApiArg) { if (data != "") {
val postData: ByteArray = data.toByteArray(StandardCharsets.UTF_8) val postData: ByteArray = data.toByteArray(StandardCharsets.UTF_8)
val outputStream = DataOutputStream(outputStream) val outputStream = DataOutputStream(outputStream)
outputStream.write(postData) outputStream.write(postData)
@ -34,13 +36,12 @@ class DropBox(){
val reader = BufferedReader(InputStreamReader(inputStream)) val reader = BufferedReader(InputStreamReader(inputStream))
val output = reader.readText() val output = reader.readText()
println("\nSent 'GET' request to URL : $url; Response Code : $responseCode")
println(output) println(output)
return output return output
} } catch (ex: Exception) {
catch (ex:Exception){
println(ex.message) println(ex.message)
val reader = BufferedReader(InputStreamReader(errorStream))
println(reader.readText())
return "Error!" return "Error!"
} }
} }
@ -48,16 +49,22 @@ class DropBox(){
fun getFolderList(folder:String):FolderList{ fun getFolderList(folder:String):FolderList{
val response = dropboxApi("https://api.dropboxapi.com/2/files/list_folder", val response = dropboxApi("https://api.dropboxapi.com/2/files/list_folder",
"{\"path\":\"$folder\"}") "{\"path\":\"$folder\"}","application/json")
return GameSaver().json().fromJson(FolderList::class.java,response) return GameSaver().json().fromJson(FolderList::class.java,response)
} }
fun getFileInfo(fileName:String):String{ fun downloadFile(fileName:String):String{
val response = dropboxApi("https://content.dropboxapi.com/2/files/download", val response = dropboxApi("https://content.dropboxapi.com/2/files/download",
"{\"path\":\"$fileName\"}",true) dropboxApiArg = "{\"path\":\"$fileName\"}")
return response return response
} }
fun uploadFile(fileName: String, data: String){
val response = dropboxApi("https://content.dropboxapi.com/2/files/upload",
data,"application/octet-stream","{\"path\":\"$fileName\"}")
}
class FolderList{ class FolderList{
var entries = ArrayList<FolderListEntry>() var entries = ArrayList<FolderListEntry>()
} }

View File

@ -96,14 +96,15 @@ class WorldScreenOptionsTable(screen:WorldScreen) : PopupTable(screen){
scrollPane.setScrollingDisabled(true,false) scrollPane.setScrollingDisabled(true,false)
add(scrollPane).maxHeight(screen.stage.height*0.6f).row() add(scrollPane).maxHeight(screen.stage.height*0.6f).row()
/*
addButton("Dropbox Testing"){ addButton("Dropbox Testing"){
// val folderList = DropBox().getFolderList("/Maps") // val folderList = DropBox().getFolderList("/Maps")
// for(folder in folderList.entries) // for(folder in folderList.entries)
// print(folder.name) // print(folder.name)
DropBox().getFileInfo("/Maps/China starts on tundra") // DropBox().downloadFile("/Maps/China starts on tundra")
DropBox().uploadFile("/Maps/Test","blabla")
} }
*/
addButton("Close"){ remove() } addButton("Close"){ remove() }