From d8ac53753531c2f95accfb838ad69b9be33f2384 Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Wed, 18 Jul 2018 23:13:58 +0300 Subject: [PATCH] Cut down saved game size when copying text to the clipboard by 85% using gzip --- core/src/com/unciv/ui/LoadScreen.kt | 3 +- core/src/com/unciv/ui/SaveScreen.kt | 68 +++++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/core/src/com/unciv/ui/LoadScreen.kt b/core/src/com/unciv/ui/LoadScreen.kt index 68c16d4670..a019304353 100644 --- a/core/src/com/unciv/ui/LoadScreen.kt +++ b/core/src/com/unciv/ui/LoadScreen.kt @@ -61,7 +61,8 @@ class LoadScreen : PickerScreen() { loadFromClipboardButton.addClickListener { try{ val clipboardContentsString = Gdx.app.clipboard.contents - val loadedGame = Json().fromJson(GameInfo::class.java, clipboardContentsString) + val decoded = Gzip.decompress(Gzip.decoder(clipboardContentsString)) + val loadedGame = Json().fromJson(GameInfo::class.java, decoded) loadedGame.setTransients() UnCivGame.Current.loadGame(loadedGame) }catch (ex:Exception){ diff --git a/core/src/com/unciv/ui/SaveScreen.kt b/core/src/com/unciv/ui/SaveScreen.kt index 44d63188a6..c30b730d33 100644 --- a/core/src/com/unciv/ui/SaveScreen.kt +++ b/core/src/com/unciv/ui/SaveScreen.kt @@ -5,6 +5,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Label import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.TextButton import com.badlogic.gdx.scenes.scene2d.ui.TextField +import com.badlogic.gdx.utils.Base64Coder import com.badlogic.gdx.utils.Json import com.unciv.UnCivGame import com.unciv.logic.GameSaver @@ -13,6 +14,14 @@ import com.unciv.ui.utils.addClickListener import com.unciv.ui.utils.enable import com.unciv.ui.utils.getRandom import com.unciv.ui.utils.tr +import java.io.BufferedReader +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.InputStreamReader +import java.util.zip.GZIPInputStream +import java.util.zip.GZIPOutputStream +import kotlin.text.Charsets.UTF_8 + class SaveScreen : PickerScreen() { val textField = TextField("", skin) @@ -35,8 +44,9 @@ class SaveScreen : PickerScreen() { val newSave = Table() val adjectives = listOf("Prancing","Obese","Junior","Senior","Abstract","Discombobulating","Simple","Awkward","Holy", - "Dangerous","Greasy","Stinky","Purple","Majestic","Incomprehensible","Cardboard","Chocolate","Robot","Ninja") - val nouns = listOf("Moose","Pigeon","Weasel","Ferret","Onion","Marshmallow","Crocodile","Inu Shiba", + "Dangerous","Greasy","Stinky","Purple","Majestic","Incomprehensible","Cardboard","Chocolate","Robot","Ninja", + "Fluffy","Magical","Invisible") + val nouns = listOf("Moose","Pigeon","Weasel","Ferret","Onion","Marshmallow","Crocodile","Unicorn", "Sandwich","Elephant","Kangaroo","Marmot","Beagle","Dolphin","Fish","Tomato","Duck","Dinosaur") val defaultSaveName = adjectives.getRandom()+" "+nouns.getRandom() textField.text = defaultSaveName @@ -45,7 +55,11 @@ class SaveScreen : PickerScreen() { newSave.add(textField).width(300f).pad(10f).row() val copyJsonButton = TextButton("Copy game info".tr(),skin) - copyJsonButton.addClickListener { Gdx.app.clipboard.contents = Json().toJson(game.gameInfo)} + copyJsonButton.addClickListener { + val json = Json().toJson(game.gameInfo) + val base64Gzip = Gzip.encoder(Gzip.compress(json)) + Gdx.app.clipboard.contents = base64Gzip + } newSave.add(copyJsonButton) topTable.add(newSave) @@ -59,4 +73,52 @@ class SaveScreen : PickerScreen() { rightSideButton.enable() } +} + + +object Gzip { + + fun compress(data: String): ByteArray { + val bos = ByteArrayOutputStream(data.length) + val gzip = GZIPOutputStream(bos) + gzip.write(data.toByteArray()) + gzip.close() + val compressed = bos.toByteArray() + bos.close() + return compressed + } + + fun decompress(compressed: ByteArray): String { + val bis = ByteArrayInputStream(compressed) + val gis = GZIPInputStream(bis) + val br = BufferedReader(InputStreamReader(gis, "UTF-8")) + val sb = StringBuilder() + var line: String? = br.readLine() + while (line != null) { + sb.append(line) + line = br.readLine() + } + br.close() + gis.close() + bis.close() + return sb.toString() + } + + + fun gzip(content: String): ByteArray { + val bos = ByteArrayOutputStream() + GZIPOutputStream(bos).bufferedWriter(UTF_8).use { it.write(content) } + return bos.toByteArray() + } + + fun ungzip(content: ByteArray): String = + GZIPInputStream(content.inputStream()).bufferedReader(UTF_8).use { it.readText() } + + fun encoder(bytes:ByteArray): String{ + return String(Base64Coder.encode(bytes)) + } + + fun decoder(base64Str: String): ByteArray{ + return Base64Coder.decode(base64Str) + } } \ No newline at end of file