Data export/import

This commit is contained in:
Anuken
2019-08-29 22:04:01 -04:00
parent ae88f286a6
commit ddca5ef25a
3 changed files with 134 additions and 42 deletions

View File

@ -164,6 +164,11 @@ cancel = Cancel
openlink = Open Link
copylink = Copy Link
back = Back
data.export = Export Data
data.import = Import Data
data.exported = Data exported.
data.invalid = This isn't valid game data.
data.import.confirm = Importing external data will erase[scarlet] all[] your current game data.\n[accent]This cannot be undone![]\n\nOnce the data is imported, your game will exit immediately.
classic.export = Export Classic Data
classic.export.text = [accent]Mindustry[] has just had a major update.\nClassic (v3.5 build 40) save or map data has been detected. Would you like to export these saves to your phone's home folder, for use in the Mindustry Classic app?
quit.confirm = Are you sure you want to quit?
@ -392,6 +397,7 @@ zone.impact0078.description = <insert description here>
zone.crags.description = <insert description here>
settings.language = Language
settings.data = Game Data
settings.reset = Reset to Defaults
settings.rebind = Rebind
settings.controls = Controls

View File

@ -2,11 +2,16 @@ package io.anuke.mindustry.game;
import io.anuke.arc.*;
import io.anuke.arc.collection.*;
import io.anuke.arc.files.*;
import io.anuke.arc.util.io.*;
import io.anuke.mindustry.*;
import io.anuke.mindustry.content.*;
import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.type.*;
import java.io.*;
import java.util.zip.*;
import static io.anuke.mindustry.Vars.*;
/** Stores player unlocks. Clientside only. */
@ -29,6 +34,43 @@ public class GlobalData{
});
}
public void exportData(FileHandle file) throws IOException{
Array<FileHandle> files = new Array<>();
files.add(Core.settings.getSettingsFile());
files.addAll(customMapDirectory.list());
files.addAll(saveDirectory.list());
String base = Core.settings.getDataDirectory().path();
try(OutputStream fos = file.write(false, 2048); ZipOutputStream zos = new ZipOutputStream(fos)){
for(FileHandle add : files){
zos.putNextEntry(new ZipEntry(add.path().substring(base.length())));
Streams.copyStream(add.read(), zos);
zos.closeEntry();
}
}
}
public void importData(FileHandle file){
FileHandle zipped = new ZipFileHandle(file);
FileHandle base = Core.settings.getDataDirectory();
if(!base.child("settings.bin").exists()){
throw new IllegalArgumentException("Not valid save data.");
}
//purge existing data
for(FileHandle f : base.list()){
if(f.isDirectory()){
f.deleteDirectory();
}else{
f.delete();
}
}
zipped.walk(f -> f.copyTo(base.child(f.path())));
}
public void modified(){
modified = true;
}

View File

@ -22,12 +22,13 @@ import static io.anuke.arc.Core.bundle;
import static io.anuke.mindustry.Vars.*;
public class SettingsMenuDialog extends SettingsDialog{
public SettingsTable graphics;
public SettingsTable game;
public SettingsTable sound;
private SettingsTable graphics;
private SettingsTable game;
private SettingsTable sound;
private Table prefs;
private Table menu;
private FloatingDialog dataDialog;
private boolean wasPaused;
public SettingsMenuDialog(){
@ -75,6 +76,85 @@ public class SettingsMenuDialog extends SettingsDialog{
prefs.clearChildren();
prefs.add(menu);
dataDialog = new FloatingDialog("$settings.data");
dataDialog.addCloseButton();
dataDialog.cont.table("button", t -> {
t.defaults().size(240f, 60f).left();
String style = "clear";
t.addButton("$settings.cleardata", style, () -> ui.showConfirm("$confirm", "$settings.clearall.confirm", () -> {
ObjectMap<String, Object> map = new ObjectMap<>();
for(String value : Core.settings.keys()){
if(value.contains("usid") || value.contains("uuid")){
map.put(value, Core.settings.getString(value));
}
}
Core.settings.clear();
Core.settings.putAll(map);
Core.settings.save();
for(FileHandle file : dataDirectory.list()){
file.deleteDirectory();
}
Core.app.exit();
}));
t.row();
if(android && (Core.files.local("mindustry-maps").exists() || Core.files.local("mindustry-saves").exists())){
t.addButton("$classic.export", style, () -> {
control.checkClassicData();
});
}
t.row();
t.addButton("$data.export", style, () -> {
if(ios){
FileHandle file = Core.files.local("mindustry-data-export.zip");
try{
data.exportData(file);
}catch(Exception e){
ui.showError(Strings.parseException(e, true));
}
Platform.instance.shareFile(file);
}else{
Platform.instance.showFileChooser("$data.export", "Zip Files", file -> {
FileHandle ff = file;
if(!ff.extension().equals("zip")){
ff = ff.sibling(ff.nameWithoutExtension() + ".zip");
}
try{
data.exportData(ff);
ui.showInfo("$data.exported");
}catch(Exception e){
e.printStackTrace();
ui.showError(Strings.parseException(e, true));
}
}, false, f -> false);
}
});
t.row();
//iOS doesn't have a file chooser.
if(!ios){
t.addButton("$data.import", style, () -> ui.showConfirm("$confirm", "$data.import.confirm", () -> Platform.instance.showFileChooser("$data.import", "Zip Files", file -> {
try{
data.importData(file);
Core.app.exit();
}catch(IllegalArgumentException e){
ui.showError("$data.invalid");
}catch(Exception e){
e.printStackTrace();
ui.showError(Strings.parseException(e, true));
}
}, true, f -> f.equalsIgnoreCase("zip"))));
}
});
ScrollPane pane = new ScrollPane(prefs);
pane.addCaptureListener(new InputListener(){
@Override
@ -121,6 +201,9 @@ public class SettingsMenuDialog extends SettingsDialog{
menu.row();
menu.addButton("$settings.controls", style, ui.controls::show);
}
menu.row();
menu.addButton("$settings.data", style, () -> dataDialog.show());
}
void addSettings(){
@ -141,31 +224,6 @@ public class SettingsMenuDialog extends SettingsDialog{
game.checkPref("savecreate", true);
game.pref(new Setting(){
@Override
public void add(SettingsTable table){
table.addButton("$settings.cleardata", () -> ui.showConfirm("$confirm", "$settings.clearall.confirm", () -> {
ObjectMap<String, Object> map = new ObjectMap<>();
for(String value : Core.settings.keys()){
if(value.contains("usid") || value.contains("uuid")){
map.put(value, Core.settings.getString(value));
}
}
Core.settings.clear();
Core.settings.putAll(map);
Core.settings.save();
for(FileHandle file : dataDirectory.list()){
file.deleteDirectory();
}
Core.app.exit();
})).size(220f, 60f).pad(6).left();
table.add();
table.row();
}
});
game.pref(new Setting(){
@Override
public void add(SettingsTable table){
@ -179,20 +237,6 @@ public class SettingsMenuDialog extends SettingsDialog{
}
});
if(android && (Core.files.local("mindustry-maps").exists() || Core.files.local("mindustry-saves").exists())){
game.pref(new Setting(){
@Override
public void add(SettingsTable table){
table.addButton("$classic.export", () -> {
control.checkClassicData();
}).size(220f, 60f).pad(6).left();
table.add();
table.row();
hide();
}
});
}
graphics.sliderPref("uiscale", 100, 25, 400, 25, s -> {
if(ui.settings != null){
Core.settings.put("uiscalechanged", true);