Added Unzip functionality - we should soon be ready for mod management from within the game!
This commit is contained in:
parent
16356f9d36
commit
a253a97940
8 changed files with 702 additions and 623 deletions
BIN
android/Images/OtherIcons/Mods.png
Normal file
BIN
android/Images/OtherIcons/Mods.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
File diff suppressed because it is too large
Load diff
Binary file not shown.
Before Width: | Height: | Size: 869 KiB After Width: | Height: | Size: 871 KiB |
Binary file not shown.
Before Width: | Height: | Size: 485 KiB After Width: | Height: | Size: 482 KiB |
|
@ -70,46 +70,47 @@ class MainMenuScreen: CameraStageBaseScreen() {
|
|||
}
|
||||
}
|
||||
|
||||
val table = Table().apply { defaults().pad(10f) }
|
||||
val column1 = Table().apply { defaults().pad(10f) }
|
||||
val column2 = Table().apply { defaults().pad(10f) }
|
||||
val autosaveGame = GameSaver.getSave(autosave, false)
|
||||
if (autosaveGame.exists()) {
|
||||
val resumeTable = getTableBlock("Resume","OtherIcons/Resume") { autoLoadGame() }
|
||||
table.add(resumeTable).row()
|
||||
column1.add(resumeTable).row()
|
||||
}
|
||||
|
||||
val quickstartTable = getTableBlock("Quickstart", "OtherIcons/Quickstart") { quickstartNewGame() }
|
||||
table.add(quickstartTable).row()
|
||||
column1.add(quickstartTable).row()
|
||||
|
||||
val newGameButton = getTableBlock("Start new game", "OtherIcons/New") {
|
||||
game.setScreen(NewGameScreen(this))
|
||||
dispose()
|
||||
}
|
||||
table.add(newGameButton).row()
|
||||
column1.add(newGameButton).row()
|
||||
|
||||
if (GameSaver.getSaves(false).any()) {
|
||||
val loadGameTable = getTableBlock("Load game", "OtherIcons/Load")
|
||||
{ game.setScreen(LoadGameScreen(this)) }
|
||||
table.add(loadGameTable).row()
|
||||
column1.add(loadGameTable).row()
|
||||
}
|
||||
|
||||
val multiplayerTable = getTableBlock("Multiplayer", "OtherIcons/Multiplayer")
|
||||
{ game.setScreen(MultiplayerScreen(this)) }
|
||||
table.add(multiplayerTable).row()
|
||||
column2.add(multiplayerTable).row()
|
||||
|
||||
val mapEditorScreenTable = getTableBlock("Map editor", "OtherIcons/MapEditor")
|
||||
{ if(stage.actors.none { it is MapEditorMainScreenPopup }) MapEditorMainScreenPopup(this) }
|
||||
table.add(mapEditorScreenTable).padBottom(0f)
|
||||
{ if(stage.actors.none { it is MapEditorMainScreenPopup }) MapEditorMainScreenPopup(this) }
|
||||
column2.add(mapEditorScreenTable).row()
|
||||
|
||||
// set the same width for all buttons
|
||||
table.cells.first().padTop(0f)
|
||||
table.pack()
|
||||
table.children.filterIsInstance<Table>().forEach {
|
||||
it.align(Align.left)
|
||||
it.moveBy((it.width - table.width) / 2, 0f)
|
||||
it.width = table.width
|
||||
}
|
||||
// val modsTable = getTableBlock("Mods", "OtherIcons/Mods")
|
||||
// { if(stage.actors.none { it is MapEditorMainScreenPopup }) MapEditorMainScreenPopup(this) }
|
||||
// column2.add(modEditorTable).row()
|
||||
|
||||
|
||||
val table=Table().apply { defaults().pad(10f) }
|
||||
table.add(column1)
|
||||
table.add(column2)
|
||||
table.pack()
|
||||
|
||||
val scroll = ScrollPane(table)
|
||||
scroll.setSize(table.width, stage.height * 0.98f)
|
||||
scroll.center(stage)
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
package com.unciv.ui.worldscreen.mainmenu
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.files.FileHandle
|
||||
import com.unciv.logic.GameInfo
|
||||
import com.unciv.logic.GameSaver
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.ui.saves.Gzip
|
||||
import java.io.BufferedReader
|
||||
import java.io.DataOutputStream
|
||||
import java.io.InputStream
|
||||
import java.io.InputStreamReader
|
||||
import java.io.*
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URL
|
||||
import java.nio.charset.Charset
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
|
||||
object DropBox {
|
||||
|
||||
fun dropboxApi(url:String, data:String="",contentType:String="",dropboxApiArg:String=""): InputStream? {
|
||||
fun dropboxApi(url: String, data: String = "", contentType: String = "", dropboxApiArg: String = ""): InputStream? {
|
||||
|
||||
with(URL(url).openConnection() as HttpURLConnection) {
|
||||
requestMethod = "POST" // default is GET
|
||||
|
@ -45,45 +47,45 @@ object DropBox {
|
|||
}
|
||||
}
|
||||
|
||||
fun getFolderList(folder:String): ArrayList<FolderListEntry> {
|
||||
fun getFolderList(folder: String): ArrayList<FolderListEntry> {
|
||||
val folderList = ArrayList<FolderListEntry>()
|
||||
// The DropBox API returns only partial file listings from one request. list_folder and
|
||||
// list_folder/continue return similar responses, but list_folder/continue requires a cursor
|
||||
// instead of the path.
|
||||
val response = dropboxApi("https://api.dropboxapi.com/2/files/list_folder",
|
||||
"{\"path\":\"$folder\"}","application/json")
|
||||
"{\"path\":\"$folder\"}", "application/json")
|
||||
var currentFolderListChunk = GameSaver.json().fromJson(FolderList::class.java, response)
|
||||
folderList.addAll(currentFolderListChunk.entries)
|
||||
while (currentFolderListChunk.has_more) {
|
||||
val continuationResponse = dropboxApi("https://api.dropboxapi.com/2/files/list_folder/continue",
|
||||
"{\"cursor\":\"${currentFolderListChunk.cursor}\"}","application/json")
|
||||
"{\"cursor\":\"${currentFolderListChunk.cursor}\"}", "application/json")
|
||||
currentFolderListChunk = GameSaver.json().fromJson(FolderList::class.java, continuationResponse)
|
||||
folderList.addAll(currentFolderListChunk.entries)
|
||||
}
|
||||
return folderList
|
||||
}
|
||||
|
||||
fun downloadFile(fileName:String): InputStream {
|
||||
fun downloadFile(fileName: String): InputStream {
|
||||
val response = dropboxApi("https://content.dropboxapi.com/2/files/download",
|
||||
contentType = "text/plain",dropboxApiArg = "{\"path\":\"$fileName\"}")
|
||||
contentType = "text/plain", dropboxApiArg = "{\"path\":\"$fileName\"}")
|
||||
return response!!
|
||||
}
|
||||
|
||||
fun downloadFileAsString(fileName:String): String {
|
||||
fun downloadFileAsString(fileName: String): String {
|
||||
val inputStream = downloadFile(fileName)
|
||||
val text = BufferedReader(InputStreamReader(inputStream)).readText()
|
||||
return text
|
||||
}
|
||||
|
||||
fun uploadFile(fileName: String, data: String, overwrite:Boolean=false){
|
||||
fun uploadFile(fileName: String, data: String, overwrite: Boolean = false){
|
||||
val overwriteModeString = if(!overwrite) "" else ""","mode":{".tag":"overwrite"}"""
|
||||
dropboxApi("https://content.dropboxapi.com/2/files/upload",
|
||||
data,"application/octet-stream", """{"path":"$fileName"$overwriteModeString}""")
|
||||
data, "application/octet-stream", """{"path":"$fileName"$overwriteModeString}""")
|
||||
}
|
||||
|
||||
fun deleteFile(fileName:String){
|
||||
fun deleteFile(fileName: String){
|
||||
dropboxApi("https://api.dropboxapi.com/2/files/delete_v2",
|
||||
"{\"path\":\"$fileName\"}","application/json")
|
||||
"{\"path\":\"$fileName\"}", "application/json")
|
||||
}
|
||||
//
|
||||
// fun createTemplate(): String {
|
||||
|
@ -108,11 +110,11 @@ object DropBox {
|
|||
}
|
||||
|
||||
class OnlineMultiplayer {
|
||||
fun getGameLocation(gameId:String) = "/MultiplayerGames/$gameId"
|
||||
fun getGameLocation(gameId: String) = "/MultiplayerGames/$gameId"
|
||||
|
||||
fun tryUploadGame(gameInfo: GameInfo){
|
||||
val zippedGameInfo = Gzip.zip(GameSaver.json().toJson(gameInfo))
|
||||
DropBox.uploadFile(getGameLocation(gameInfo.gameId),zippedGameInfo,true)
|
||||
DropBox.uploadFile(getGameLocation(gameInfo.gameId), zippedGameInfo, true)
|
||||
}
|
||||
|
||||
fun tryDownloadGame(gameId: String): GameInfo {
|
||||
|
@ -130,3 +132,62 @@ class OnlineMultiplayer {
|
|||
return GameSaver.currentTurnCivFromString(Gzip.unzip(zippedGameInfo))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
object Zip {
|
||||
fun downloadAndExtract(dropboxFileLocation:String, folderFileHandle:FileHandle){
|
||||
val fileFromDropbox = DropBox.downloadFile(dropboxFileLocation)
|
||||
val tempZipFileHandle = folderFileHandle.child("tempZip.zip")
|
||||
tempZipFileHandle.write(fileFromDropbox, false)
|
||||
extractFolder(tempZipFileHandle.path())
|
||||
}
|
||||
|
||||
// I went through a lot of similar answers that didn't work until I got to this gem by NeilMonday
|
||||
// https://stackoverflow.com/questions/981578/how-to-unzip-files-recursively-in-java
|
||||
fun extractFolder(zipFile: String) {
|
||||
println(zipFile)
|
||||
val BUFFER = 2048
|
||||
val file = File(zipFile)
|
||||
val zip = ZipFile(file)
|
||||
val newPath = zipFile.substring(0, zipFile.length - 4)
|
||||
File(newPath).mkdir()
|
||||
val zipFileEntries = zip.entries()
|
||||
|
||||
// Process each entry
|
||||
while (zipFileEntries.hasMoreElements()) {
|
||||
// grab a zip file entry
|
||||
val entry = zipFileEntries.nextElement() as ZipEntry
|
||||
val currentEntry = entry.name
|
||||
val destFile = File(newPath, currentEntry)
|
||||
//destFile = new File(newPath, destFile.getName());
|
||||
val destinationParent = destFile.parentFile
|
||||
|
||||
// create the parent directory structure if needed
|
||||
destinationParent.mkdirs()
|
||||
if (!entry.isDirectory) {
|
||||
val inputStream = BufferedInputStream(zip
|
||||
.getInputStream(entry))
|
||||
var currentByte: Int
|
||||
// establish buffer for writing file
|
||||
val data = ByteArray(BUFFER)
|
||||
|
||||
// write the current file to disk
|
||||
val fos = FileOutputStream(destFile)
|
||||
val dest = BufferedOutputStream(fos,
|
||||
BUFFER)
|
||||
|
||||
// read and write until last byte is encountered
|
||||
while (inputStream.read(data, 0, BUFFER).also { currentByte = it } != -1) {
|
||||
dest.write(data, 0, currentByte)
|
||||
}
|
||||
dest.flush()
|
||||
dest.close()
|
||||
inputStream.close()
|
||||
}
|
||||
if (currentEntry.endsWith(".zip")) {
|
||||
// found a zip file, try to open
|
||||
extractFolder(destFile.absolutePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -528,6 +528,7 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
|
|||
* [Go back](https://thenounproject.com/search/?q=go%20back&i=1901947) by Salvia Santos for Resume
|
||||
* [Multiplayer](https://thenounproject.com/search/?q=multiplayer&i=1215652) by Roy Charles
|
||||
* [Options](https://thenounproject.com/search/?q=options&i=866090) By Thengakola
|
||||
* [Package](https://thenounproject.com/search/?q=package&i=1886048) by shashank singh
|
||||
|
||||
# Sound credits
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
package com.unciv.testing
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.files.FileHandle
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.UncivGameParameters
|
||||
import com.unciv.models.metadata.GameSettings
|
||||
|
@ -11,10 +12,12 @@ import com.unciv.models.ruleset.unit.BaseUnit
|
|||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.worldscreen.mainmenu.Zip
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import java.io.File
|
||||
|
||||
@RunWith(GdxTestRunner::class)
|
||||
class BasicTests {
|
||||
|
@ -79,4 +82,10 @@ class BasicTests {
|
|||
val x = "+1 Gold, +2 Production".tr()
|
||||
print(x)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun tryUnzip(){
|
||||
// Zip.extractFolder("""C:\Users\LENOVO\Downloads\Rebuild.rar""")
|
||||
Zip.downloadAndExtract("/Mods/Reasoures.zip", FileHandle("""C:\Users\LENOVO\Downloads"""))
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue