diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 5345273c4e..03c38a2746 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -174,6 +174,7 @@ save.playtime = Playtime: {0} warning = Warning. confirm = Confirm delete = Delete +view.workshop = View In Workshop ok = OK open = Open customize = Customize Rules @@ -222,6 +223,7 @@ editor.oregen.info = Ore Generation: editor.mapinfo = Map Info editor.author = Author: editor.description = Description: +editor.nodescription = A map must have a description of at least 4 characters before being published. editor.waves = Waves: editor.rules = Rules: editor.generation = Generation: diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index 720b7d33bf..445a634714 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -139,7 +139,7 @@ public class Vars implements Loadable{ public static EntityCollisions collisions; public static DefaultWaves defaultWaves; public static LoopControl loops; - public static Platform platform; + public static Platform platform = new Platform(){}; public static Plugins plugins; public static World world; diff --git a/core/src/io/anuke/mindustry/core/Platform.java b/core/src/io/anuke/mindustry/core/Platform.java index 29e5c0d5ea..55c57e82a4 100644 --- a/core/src/io/anuke/mindustry/core/Platform.java +++ b/core/src/io/anuke/mindustry/core/Platform.java @@ -31,6 +31,9 @@ public interface Platform{ return Array.with(); } + /** Steam: View a map listing on the workshop.*/ + default void viewMapListing(Map map){} + /** Steam: Open workshop for maps.*/ default void openWorkshop(){} diff --git a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java index 8f2dd20d92..773ce88749 100644 --- a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java @@ -154,9 +154,20 @@ public class MapEditorDialog extends Dialog implements Disposable{ if(steam){ menu.cont.addImageTextButton("$editor.publish.workshop", Icon.linkSmall, () -> { Map map = save(); - if(map != null){ - platform.publishMap(map); + + if(map == null) return; + + if(map.tags.get("description", "").length() < 4){ + ui.showErrorMessage("$editor.nodescription"); + return; } + + if(!Gamemode.survival.valid(map)){ + ui.showErrorMessage("$map.nospawn"); + return; + } + + platform.publishMap(map); }).padTop(-3).size(swidth * 2f + 10, 60f); menu.cont.row(); @@ -276,7 +287,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ }); } - private Map save(){ + public Map save(){ String name = editor.getTags().get("name", "").trim(); editor.getTags().put("rules", JsonIO.write(state.rules)); editor.getTags().remove("width"); diff --git a/core/src/io/anuke/mindustry/maps/Map.java b/core/src/io/anuke/mindustry/maps/Map.java index df0a2d711f..94fa841f08 100644 --- a/core/src/io/anuke/mindustry/maps/Map.java +++ b/core/src/io/anuke/mindustry/maps/Map.java @@ -64,7 +64,7 @@ public class Map implements Comparable{ } public FileHandle previewFile(){ - return Vars.mapPreviewDirectory.child(file.nameWithoutExtension() + ".png"); + return Vars.mapPreviewDirectory.child((workshop ? file.parent().name() : file.nameWithoutExtension()) + ".png"); } public FileHandle cacheFile(){ @@ -133,6 +133,8 @@ public class Map implements Comparable{ @Override public int compareTo(Map map){ + int work = -Boolean.compare(workshop, map.workshop); + if(work != 0) return work; int type = -Boolean.compare(custom, map.custom); if(type != 0) return type; int modes = Boolean.compare(Gamemode.pvp.valid(this), Gamemode.pvp.valid(map)); diff --git a/core/src/io/anuke/mindustry/maps/MapPreviewLoader.java b/core/src/io/anuke/mindustry/maps/MapPreviewLoader.java index 262f3dc45f..da229addce 100644 --- a/core/src/io/anuke/mindustry/maps/MapPreviewLoader.java +++ b/core/src/io/anuke/mindustry/maps/MapPreviewLoader.java @@ -6,6 +6,7 @@ import io.anuke.arc.assets.loaders.resolvers.*; import io.anuke.arc.collection.*; import io.anuke.arc.files.*; import io.anuke.arc.graphics.*; +import io.anuke.arc.util.*; import io.anuke.mindustry.*; import io.anuke.mindustry.game.*; @@ -20,7 +21,7 @@ public class MapPreviewLoader extends TextureLoader{ try{ super.loadAsync(manager, fileName, file.sibling(file.nameWithoutExtension()), parameter); }catch(Exception e){ - e.printStackTrace(); + Log.err(e); MapPreviewParameter param = (MapPreviewParameter)parameter; Vars.maps.queueNewPreview(param.map); } @@ -31,11 +32,11 @@ public class MapPreviewLoader extends TextureLoader{ try{ return super.loadSync(manager, fileName, file, parameter); }catch(Throwable e){ - e.printStackTrace(); + Log.err(e); try{ return new Texture(file); }catch(Throwable e2){ - e2.printStackTrace(); + Log.err(e2); return new Texture("sprites/error.png"); } } diff --git a/core/src/io/anuke/mindustry/maps/Maps.java b/core/src/io/anuke/mindustry/maps/Maps.java index dd45cc9e6f..395ceafec6 100644 --- a/core/src/io/anuke/mindustry/maps/Maps.java +++ b/core/src/io/anuke/mindustry/maps/Maps.java @@ -324,10 +324,8 @@ public class Maps{ public void loadPreviews(){ for(Map map : maps){ - Log.info("Generating preview for {0}", map.name()); //try to load preview if(map.previewFile().exists()){ - Log.info("> exists"); //this may fail, but calls queueNewPreview Core.assets.load(new AssetDescriptor<>(map.previewFile().path() + "." + mapExtension, Texture.class, new MapPreviewParameter(map))).loaded = t -> map.texture = (Texture)t; @@ -338,7 +336,6 @@ public class Maps{ queueNewPreview(map); } }else{ - Log.info("> doesn't exist, queuing"); queueNewPreview(map); } } @@ -347,7 +344,6 @@ public class Maps{ private void createAllPreviews(){ Core.app.post(() -> { for(Map map : previewList){ - Log.info("> > GEN NEW preview for {0}", map.name()); createNewPreview(map, e -> Core.app.post(() -> map.texture = Core.assets.get("sprites/error.png"))); } previewList.clear(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java index 66de040bb2..c6b2dabe60 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java @@ -4,7 +4,6 @@ import io.anuke.arc.*; import io.anuke.arc.graphics.*; import io.anuke.arc.input.*; import io.anuke.arc.math.*; -import io.anuke.arc.scene.event.*; import io.anuke.arc.scene.ui.*; import io.anuke.arc.scene.ui.layout.*; import io.anuke.arc.util.*; @@ -205,13 +204,17 @@ public class MapsDialog extends FloatingDialog{ } }).fillX().height(54f).marginLeft(10); - table.addImageTextButton("$delete", Icon.trash16Small, () -> { - ui.showConfirm("$confirm", Core.bundle.format("map.delete", map.name()), () -> { - maps.removeMap(map); - dialog.hide(); - setup(); - }); - }).fillX().height(54f).marginLeft(10).disabled(!map.custom).touchable(map.custom ? Touchable.enabled : Touchable.disabled); + table.addImageTextButton(map.workshop ? "$view.workshop" : "$delete", map.workshop ? Icon.linkSmall : Icon.trash16Small, () -> { + if(map.workshop){ + platform.viewMapListing(map); + }else{ + ui.showConfirm("$confirm", Core.bundle.format("map.delete", map.name()), () -> { + maps.removeMap(map); + dialog.hide(); + setup(); + }); + } + }).fillX().height(54f).marginLeft(10).disabled(!map.workshop && !map.custom); dialog.show(); } diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java index d4cb2582c2..d215e28d9c 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java @@ -202,6 +202,11 @@ public class DesktopLauncher extends ClientLauncher{ return !steam ? super.getExternalMaps() : SVars.workshop.getMapFiles(); } + @Override + public void viewMapListing(Map map){ + SVars.net.friends.activateGameOverlayToWebPage("steam://url/CommunityFilePage/" + map.file.parent().name()); + } + @Override public NetProvider getNet(){ return steam ? SVars.net : new ArcNetImpl(); diff --git a/desktop/src/io/anuke/mindustry/desktop/steam/SWorkshop.java b/desktop/src/io/anuke/mindustry/desktop/steam/SWorkshop.java index fd9f360084..f233218fd1 100644 --- a/desktop/src/io/anuke/mindustry/desktop/steam/SWorkshop.java +++ b/desktop/src/io/anuke/mindustry/desktop/steam/SWorkshop.java @@ -39,6 +39,15 @@ public class SWorkshop implements SteamUGCCallback{ } public void publishMap(Map map){ + if(map.tags.containsKey("steamid")){ + Log.info("Map already published, redirecting to ID."); + SVars.net.friends.activateGameOverlayToWebPage("steam://url/CommunityFilePage/" + map.tags.get("steamid")); + return; + } + + //update author name when publishing + map.tags.put("author", SVars.net.friends.getPersonaName()); + FloatingDialog dialog = new FloatingDialog("$confirm"); dialog.setFillParent(false); dialog.cont.add("$map.publish.confirm").width(600f).wrap(); @@ -141,6 +150,12 @@ public class SWorkshop implements SteamUGCCallback{ if(needsToAcceptWLA){ SVars.net.friends.activateGameOverlayToWebPage("https://steamcommunity.com/sharedfiles/workshoplegalagreement"); } + ui.editor.editor.getTags().put("steamid", SteamNativeHandle.getNativeHandle(publishedFileID) + ""); + try{ + ui.editor.save(); + }catch(Exception e){ + Log.err(e); + } Events.fire(new MapPublishEvent()); }else{ ui.showErrorMessage(Core.bundle.format("map.publish.error ", result.name())); diff --git a/gradle.properties b/gradle.properties index 119b9bb609..f47982435b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=de8be7efb888294932a9d41140ac9a71b4ff7f18 +archash=818e26ff093403031fcf31d3424dacb9c646d4b6