From 940965f03d3fc2b7f49f24500c3575c6d1bf0b27 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 31 May 2019 10:24:51 -0400 Subject: [PATCH] .mmap file importing / Better exception parsing --- .../io/anuke/mindustry/AndroidLauncher.java | 13 ++++--- core/assets/bundles/bundle.properties | 3 ++ core/src/io/anuke/mindustry/Vars.java | 3 ++ core/src/io/anuke/mindustry/core/Control.java | 2 +- .../src/io/anuke/mindustry/core/Platform.java | 5 +-- core/src/io/anuke/mindustry/core/UI.java | 16 ++++++--- .../mindustry/editor/MapEditorDialog.java | 34 +++++++++--------- .../io/anuke/mindustry/io/LegacyMapIO.java | 3 ++ core/src/io/anuke/mindustry/maps/Maps.java | 33 +++++++++++++++-- core/src/io/anuke/mindustry/net/Net.java | 5 ++- .../mindustry/ui/dialogs/FileChooser.java | 6 ++++ .../mindustry/ui/dialogs/HostDialog.java | 2 +- .../mindustry/ui/dialogs/LoadDialog.java | 10 +++--- .../mindustry/ui/dialogs/MapsDialog.java | 35 +++++++++++-------- .../mindustry/desktop/DesktopPlatform.java | 13 +++---- ios/src/io/anuke/mindustry/IOSLauncher.java | 2 +- 16 files changed, 119 insertions(+), 66 deletions(-) diff --git a/android/src/io/anuke/mindustry/AndroidLauncher.java b/android/src/io/anuke/mindustry/AndroidLauncher.java index 7571b3f746..3f75f746fe 100644 --- a/android/src/io/anuke/mindustry/AndroidLauncher.java +++ b/android/src/io/anuke/mindustry/AndroidLauncher.java @@ -15,16 +15,15 @@ import io.anuke.arc.backends.android.surfaceview.AndroidApplication; import io.anuke.arc.backends.android.surfaceview.AndroidApplicationConfiguration; import io.anuke.arc.files.FileHandle; import io.anuke.arc.function.Consumer; +import io.anuke.arc.function.Predicate; import io.anuke.arc.scene.ui.layout.Unit; import io.anuke.arc.util.Strings; import io.anuke.arc.util.serialization.Base64Coder; import io.anuke.mindustry.core.Platform; import io.anuke.mindustry.game.Saves.SaveSlot; import io.anuke.mindustry.io.SaveIO; -import io.anuke.mindustry.net.Net; +import io.anuke.mindustry.net.*; import io.anuke.mindustry.ui.dialogs.FileChooser; -import io.anuke.mindustry.net.ArcNetClient; -import io.anuke.mindustry.net.ArcNetServer; import java.io.*; import java.util.ArrayList; @@ -72,10 +71,10 @@ public class AndroidLauncher extends AndroidApplication{ } @Override - public void showFileChooser(String text, String content, Consumer cons, boolean open, String filetype){ - chooser = new FileChooser(text, file -> file.extension().equalsIgnoreCase(filetype), open, cons); + public void showFileChooser(String text, String content, Consumer cons, boolean open, Predicate filetype){ + chooser = new FileChooser(text, file -> filetype.test(file.extension().toLowerCase()), open, cons); if(Build.VERSION.SDK_INT < Build.VERSION_CODES.M || (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && - checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)){ + checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)){ chooser.show(); chooser = null; }else{ @@ -157,7 +156,7 @@ public class AndroidLauncher extends AndroidApplication{ SaveSlot slot = control.saves.importSave(file); ui.load.runLoadSave(slot); }catch(IOException e){ - ui.showError(Core.bundle.format("save.import.fail", Strings.parseException(e, false))); + ui.showError(Core.bundle.format("save.import.fail", Strings.parseException(e, true))); } }else{ ui.showError("$save.import.invalid"); diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index aded4c80ec..1155215b4d 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -219,6 +219,9 @@ editor.teams = Teams editor.elevation = Elevation editor.errorload = Error loading file:\n[accent]{0} editor.errorsave = Error saving file:\n[accent]{0} +editor.errorimage = That's an image, not a map. Don't go around changing extensions expecting it to work.\n\nIf you want to import a legacy map, use the 'import legacy map' button in the editor. +editor.errorlegacy = This map is too old, and uses a legacy map format that is no longer supported. +editor.errorheader = This map file is either not valid or corrupt. editor.errorname = Map has no name defined. editor.update = Update editor.randomize = Randomize diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index 297c78f82d..6c187799b9 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -105,6 +105,8 @@ public class Vars{ public static FileHandle screenshotDirectory; /** data subdirectory used for custom mmaps */ public static FileHandle customMapDirectory; + /** tmp subdirectory for map conversion */ + public static FileHandle tmpDirectory; /** data subdirectory used for saves */ public static FileHandle saveDirectory; /** old map file extension, for conversion */ @@ -206,5 +208,6 @@ public class Vars{ screenshotDirectory = dataDirectory.child("screenshots/"); customMapDirectory = dataDirectory.child("maps/"); saveDirectory = dataDirectory.child("saves/"); + tmpDirectory = dataDirectory.child("tmp/"); } } diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 7bfb76aac8..97574e4662 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -135,7 +135,7 @@ public class Control implements ApplicationListener{ Net.host(port); player.isAdmin = true; }catch(IOException e){ - ui.showError(Core.bundle.format("server.error", Strings.parseException(e, false))); + ui.showError(Core.bundle.format("server.error", Strings.parseException(e, true))); Core.app.post(() -> state.set(State.menu)); } } diff --git a/core/src/io/anuke/mindustry/core/Platform.java b/core/src/io/anuke/mindustry/core/Platform.java index 381865907b..85026c9335 100644 --- a/core/src/io/anuke/mindustry/core/Platform.java +++ b/core/src/io/anuke/mindustry/core/Platform.java @@ -4,6 +4,7 @@ import io.anuke.arc.Core; import io.anuke.arc.Input.TextInput; import io.anuke.arc.files.FileHandle; import io.anuke.arc.function.Consumer; +import io.anuke.arc.function.Predicate; import io.anuke.arc.math.RandomXS128; import io.anuke.arc.scene.ui.TextField; import io.anuke.arc.util.serialization.Base64Coder; @@ -66,14 +67,14 @@ public abstract class Platform{ } /** - * Show a file chooser. Desktop only. + * Show a file chooser. * @param text File chooser title text * @param content Description of the type of files to be loaded * @param cons Selection listener * @param open Whether to open or save files * @param filetype File extension to filter */ - public void showFileChooser(String text, String content, Consumer cons, boolean open, String filetype){ + public void showFileChooser(String text, String content, Consumer cons, boolean open, Predicate filetype){ } /** Hide the app. Android only. */ diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index 446ff0ef9d..ef57acaa8b 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -25,8 +25,7 @@ import io.anuke.mindustry.ui.dialogs.*; import io.anuke.mindustry.ui.fragments.*; import static io.anuke.arc.scene.actions.Actions.*; -import static io.anuke.mindustry.Vars.control; -import static io.anuke.mindustry.Vars.disableUI; +import static io.anuke.mindustry.Vars.*; public class UI implements ApplicationListener{ private FreeTypeFontGenerator generator; @@ -244,8 +243,17 @@ public class UI implements ApplicationListener{ } public void showError(String text){ - new Dialog("$error.title", "dialog"){{ - cont.margin(15).add(text).width(400f).wrap().get().setAlignment(Align.center, Align.center); + new Dialog("", "dialog"){{ + setFillParent(true); + cont.add("$error.title"); + cont.row(); + cont.margin(15).pane(t -> { + Label l = t.add(text).pad(14f).get(); + l.setAlignment(Align.center, Align.left); + if(mobile){ + t.getCell(l).wrap().width(400f); + } + }); buttons.addButton("$ok", this::hide).size(90, 50).pad(4); }}.show(); } diff --git a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java index 57debd5b0e..178e3f9478 100644 --- a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java @@ -21,9 +21,9 @@ import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.Platform; import io.anuke.mindustry.game.*; -import io.anuke.mindustry.io.JsonIO; -import io.anuke.mindustry.io.MapIO; +import io.anuke.mindustry.io.*; import io.anuke.mindustry.maps.Map; +import io.anuke.mindustry.ui.dialogs.FileChooser; import io.anuke.mindustry.ui.dialogs.FloatingDialog; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block.Icon; @@ -93,14 +93,16 @@ public class MapEditorDialog extends Dialog implements Disposable{ "$editor.importmap", "$editor.importmap.description", "icon-load-map", (Runnable)loadDialog::show, "$editor.importfile", "$editor.importfile.description", "icon-file", (Runnable)() -> Platform.instance.showFileChooser("$editor.loadmap", "Map Files", file -> ui.loadAnd(() -> { - try{ - //TODO what if it's an image? users should be warned for their stupidity - editor.beginEdit(MapIO.createMap(file, true)); - }catch(Exception e){ - ui.showError(Core.bundle.format("editor.errorload", Strings.parseException(e, false))); - Log.err(e); - } - }), true, mapExtension), + world.maps.tryCatchMapError(() -> { + if(MapIO.isImage(file)){ + ui.showInfo("$editor.errorimage"); + }else if(file.extension().equalsIgnoreCase(oldMapExtension)){ + editor.beginEdit(world.maps.makeLegacyMap(file)); + }else{ + editor.beginEdit(MapIO.createMap(file, true)); + } + }); + }), true, FileChooser.anyMapFiles), "$editor.importimage", "$editor.importimage.description", "icon-file-image", (Runnable)() -> Platform.instance.showFileChooser("$loadimage", "Image Files", file -> @@ -110,10 +112,10 @@ public class MapEditorDialog extends Dialog implements Disposable{ editor.beginEdit(pixmap); pixmap.dispose(); }catch(Exception e){ - ui.showError(Core.bundle.format("editor.errorload", Strings.parseException(e, false))); + ui.showError(Core.bundle.format("editor.errorload", Strings.parseException(e, true))); Log.err(e); } - }), true, "png")) + }), true, FileChooser.pngFiles)) ); t.addImageTextButton("$editor.export", "icon-save-map", isize, () -> @@ -127,11 +129,11 @@ public class MapEditorDialog extends Dialog implements Disposable{ } MapIO.writeMap(result, editor.createMap(result)); }catch(Exception e){ - ui.showError(Core.bundle.format("editor.errorsave", Strings.parseException(e, false))); + ui.showError(Core.bundle.format("editor.errorsave", Strings.parseException(e, true))); Log.err(e); } }); - }, false, mapExtension)); + }, false, FileChooser.mapFiles)); }); menu.cont.row(); @@ -158,7 +160,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ try{ editor.beginEdit(map); }catch(Exception e){ - ui.showError(Core.bundle.format("editor.errorload", Strings.parseException(e, false))); + ui.showError(Core.bundle.format("editor.errorload", Strings.parseException(e, true))); Log.err(e); } })); @@ -336,7 +338,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ show(); }catch(Exception e){ Log.err(e); - ui.showError(Core.bundle.format("editor.errorload", Strings.parseException(e, false))); + ui.showError(Core.bundle.format("editor.errorload", Strings.parseException(e, true))); } }); } diff --git a/core/src/io/anuke/mindustry/io/LegacyMapIO.java b/core/src/io/anuke/mindustry/io/LegacyMapIO.java index 753a5db125..2c65b1f2e7 100644 --- a/core/src/io/anuke/mindustry/io/LegacyMapIO.java +++ b/core/src/io/anuke/mindustry/io/LegacyMapIO.java @@ -55,6 +55,9 @@ public class LegacyMapIO{ //meta is uncompressed int version = stream.readInt(); + if(version != 1){ + throw new IOException("Outdated legacy map format"); + } int build = stream.readInt(); short width = stream.readShort(), height = stream.readShort(); byte tagAmount = stream.readByte(); diff --git a/core/src/io/anuke/mindustry/maps/Maps.java b/core/src/io/anuke/mindustry/maps/Maps.java index ba37fe1ad5..1ffdec3d31 100644 --- a/core/src/io/anuke/mindustry/maps/Maps.java +++ b/core/src/io/anuke/mindustry/maps/Maps.java @@ -3,12 +3,13 @@ package io.anuke.mindustry.maps; import io.anuke.arc.Core; import io.anuke.arc.collection.*; import io.anuke.arc.files.FileHandle; +import io.anuke.arc.function.ExceptionRunnable; import io.anuke.arc.graphics.Texture; -import io.anuke.arc.util.Disposable; -import io.anuke.arc.util.Log; +import io.anuke.arc.util.*; import io.anuke.arc.util.serialization.Json; import io.anuke.mindustry.game.SpawnGroup; -import io.anuke.mindustry.io.*; +import io.anuke.mindustry.io.LegacyMapIO; +import io.anuke.mindustry.io.MapIO; import java.io.IOException; import java.io.StringWriter; @@ -116,6 +117,14 @@ public class Maps implements Disposable{ } } + /** Creates a legacy map by converting it to a non-legacy map and pasting it in a temp directory. + * Should be followed up by {@link #importMap(FileHandle)} .*/ + public Map makeLegacyMap(FileHandle file) throws IOException{ + FileHandle dst = tmpDirectory.child("conversion_map." + mapExtension); + LegacyMapIO.convertMap(file, dst); + return MapIO.createMap(dst, true); + } + /** Import a map, then save it. This updates all values and stored data necessary. */ public void importMap(FileHandle file) throws IOException{ FileHandle dest = findFile(); @@ -124,6 +133,24 @@ public class Maps implements Disposable{ loadMap(dest, true); } + /** Attempts to run the following code; + * catches any errors and attempts to display them in a readable way.*/ + public void tryCatchMapError(ExceptionRunnable run){ + try{ + run.run(); + }catch(Exception e){ + Log.err(e); + + if("Outdated legacy map format".equals(e.getMessage())){ + ui.showError("$editor.errorlegacy"); + }else if(e.getMessage() != null && e.getMessage().contains("Incorrect header!")){ + ui.showError("$editor.errorheader"); + }else{ + ui.showError(Core.bundle.format("editor.errorload", Strings.parseException(e, true))); + } + } + } + /** Removes a map completely. */ public void removeMap(Map map){ if(map.texture != null){ diff --git a/core/src/io/anuke/mindustry/net/Net.java b/core/src/io/anuke/mindustry/net/Net.java index 7b6b770e65..58fa2716aa 100644 --- a/core/src/io/anuke/mindustry/net/Net.java +++ b/core/src/io/anuke/mindustry/net/Net.java @@ -6,8 +6,7 @@ import io.anuke.arc.collection.*; import io.anuke.arc.function.BiConsumer; import io.anuke.arc.function.Consumer; import io.anuke.arc.net.HttpRequestBuilder; -import io.anuke.arc.util.Log; -import io.anuke.arc.util.Time; +import io.anuke.arc.util.*; import io.anuke.arc.util.pooling.Pools; import io.anuke.mindustry.core.Platform; import io.anuke.mindustry.gen.Call; @@ -67,7 +66,7 @@ public class Net{ }else if(error.equals("alreadyconnected")){ error = Core.bundle.get("error.alreadyconnected"); }else if(!error.isEmpty()){ - error = Core.bundle.get("error.any") + "\n" + t.getClass().getSimpleName() + "\n" + (t.getMessage() == null ? "" : t.getMessage()); + error = Core.bundle.get("error.any") + "\n" + Strings.parseException(e, true); } ui.showText("", Core.bundle.format("connectfail", error)); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/FileChooser.java b/core/src/io/anuke/mindustry/ui/dialogs/FileChooser.java index 99b4a6d055..89317ab552 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/FileChooser.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/FileChooser.java @@ -12,6 +12,7 @@ import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.scene.ui.layout.Unit; import io.anuke.arc.util.*; import io.anuke.arc.util.pooling.Pools; +import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.Platform; import java.util.Arrays; @@ -31,6 +32,11 @@ public class FileChooser extends FloatingDialog{ private boolean open; private int lastWidth = Core.graphics.getWidth(), lastHeight = Core.graphics.getHeight(); + public static final Predicate pngFiles = str -> str.equals("png"); + public static final Predicate anyMapFiles = str -> str.equals(Vars.oldMapExtension) || str.equals(Vars.mapExtension); + public static final Predicate mapFiles = str -> str.equals(Vars.mapExtension); + public static final Predicate saveFiles = str -> str.equals(Vars.saveExtension); + public FileChooser(String title, Predicate filter, boolean open, Consumer result){ super(title); this.open = open; diff --git a/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java index a8f40dc583..dacb8fe5e4 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java @@ -56,7 +56,7 @@ public class HostDialog extends FloatingDialog{ Net.host(Vars.port); player.isAdmin = true; }catch(IOException e){ - ui.showError(Core.bundle.format("server.error", Strings.parseException(e, false))); + ui.showError(Core.bundle.format("server.error", Strings.parseException(e, true))); } ui.loadfrag.hide(); hide(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java index efdaf0adbd..880dfb3eb5 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/LoadDialog.java @@ -90,16 +90,16 @@ public class LoadDialog extends FloatingDialog{ slot.exportFile(file); setup(); }catch(IOException e){ - ui.showError(Core.bundle.format("save.export.fail", Strings.parseException(e, false))); + ui.showError(Core.bundle.format("save.export.fail", Strings.parseException(e, true))); } - }, false, saveExtension); + }, false, FileChooser.saveFiles); }else{ try{ FileHandle file = Core.files.local("save-" + slot.getName() + "." + Vars.saveExtension); slot.exportFile(file); Platform.instance.shareFile(file); }catch(Exception e){ - ui.showError(Core.bundle.format("save.export.fail", Strings.parseException(e, false))); + ui.showError(Core.bundle.format("save.export.fail", Strings.parseException(e, true))); } } }).size(14 * 3).right(); @@ -155,12 +155,12 @@ public class LoadDialog extends FloatingDialog{ setup(); }catch(IOException e){ e.printStackTrace(); - ui.showError(Core.bundle.format("save.import.fail", Strings.parseException(e, false))); + ui.showError(Core.bundle.format("save.import.fail", Strings.parseException(e, true))); } }else{ ui.showError("$save.import.invalid"); } - }, true, saveExtension); + }, true, FileChooser.saveFiles); }).fillX().margin(10f).minWidth(300f).height(70f).pad(4f).padRight(-4); } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java index 1205146ccd..aefa5e64c9 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java @@ -5,7 +5,7 @@ import io.anuke.arc.graphics.Color; import io.anuke.arc.scene.event.Touchable; import io.anuke.arc.scene.ui.*; import io.anuke.arc.scene.ui.layout.Table; -import io.anuke.arc.util.*; +import io.anuke.arc.util.Scaling; import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.Platform; import io.anuke.mindustry.io.MapIO; @@ -23,8 +23,19 @@ public class MapsDialog extends FloatingDialog{ addCloseButton(); buttons.addImageTextButton("$editor.importmap", "icon-add", 14 * 2, () -> { Platform.instance.showFileChooser("$editor.importmap", "Map File", file -> { - try{ - Map map = MapIO.createMap(file, true); + world.maps.tryCatchMapError(() -> { + if(MapIO.isImage(file)){ + ui.showError("$editor.errorimage"); + return; + } + + Map map; + if(file.extension().equalsIgnoreCase(mapExtension)){ + map = MapIO.createMap(file, true); + }else{ + map = world.maps.makeLegacyMap(file); + } + String name = map.tags.get("name"); if(name == null){ ui.showError("$editor.errorname"); @@ -34,27 +45,21 @@ public class MapsDialog extends FloatingDialog{ Map conflict = world.maps.all().find(m -> m.name().equals(name)); if(conflict != null && !conflict.custom){ - ui.showError(Core.bundle.format("editor.import.exists", name)); + ui.showInfo(Core.bundle.format("editor.import.exists", name)); }else if(conflict != null){ ui.showConfirm("$confirm", "$editor.overwrite.confirm", () -> { - try{ + world.maps.tryCatchMapError(() -> { world.maps.importMap(file); setup(); - }catch(Exception e){ - ui.showError(Core.bundle.format("editor.errorload", Strings.parseException(e, false))); - Log.err(e); - } + }); }); }else{ - world.maps.importMap(file); + world.maps.importMap(map.file); setup(); } - }catch(Exception e){ - ui.showError(Core.bundle.format("editor.errorload", Strings.parseException(e, false))); - Log.err(e); - } - }, true, mapExtension); + }); + }, true, FileChooser.anyMapFiles); }).size(230f, 64f); shown(this::setup); diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java b/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java index 22b334b1eb..fa935f50a9 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java @@ -1,14 +1,11 @@ package io.anuke.mindustry.desktop; -import club.minnced.discord.rpc.DiscordEventHandlers; -import club.minnced.discord.rpc.DiscordRPC; -import club.minnced.discord.rpc.DiscordRichPresence; +import club.minnced.discord.rpc.*; import io.anuke.arc.collection.Array; import io.anuke.arc.files.FileHandle; import io.anuke.arc.function.Consumer; -import io.anuke.arc.util.Log; -import io.anuke.arc.util.OS; -import io.anuke.arc.util.Strings; +import io.anuke.arc.function.Predicate; +import io.anuke.arc.util.*; import io.anuke.arc.util.serialization.Base64Coder; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.Platform; @@ -69,8 +66,8 @@ public class DesktopPlatform extends Platform{ } @Override - public void showFileChooser(String text, String content, Consumer cons, boolean open, String filter){ - new FileChooser(text, file -> file.extension().equalsIgnoreCase(filter), open, cons).show(); + public void showFileChooser(String text, String content, Consumer cons, boolean open, Predicate filetype){ + new FileChooser(text, file -> filetype.test(file.extension().toLowerCase()), open, cons).show(); } @Override diff --git a/ios/src/io/anuke/mindustry/IOSLauncher.java b/ios/src/io/anuke/mindustry/IOSLauncher.java index 7f9e9f43e2..1c01b4307d 100644 --- a/ios/src/io/anuke/mindustry/IOSLauncher.java +++ b/ios/src/io/anuke/mindustry/IOSLauncher.java @@ -103,7 +103,7 @@ public class IOSLauncher extends IOSApplication.Delegate{ SaveSlot slot = control.saves.importSave(file); ui.load.runLoadSave(slot); }catch(IOException e){ - ui.showError(Core.bundle.format("save.import.fail", Strings.parseException(e, false))); + ui.showError(Core.bundle.format("save.import.fail", Strings.parseException(e, true))); } }else{ ui.showError("save.import.invalid");