diff --git a/core/src/io/anuke/mindustry/mod/ContentParser.java b/core/src/io/anuke/mindustry/mod/ContentParser.java index 008ae39b63..e76ba11029 100644 --- a/core/src/io/anuke/mindustry/mod/ContentParser.java +++ b/core/src/io/anuke/mindustry/mod/ContentParser.java @@ -104,7 +104,7 @@ public class ContentParser{ return t; } - private T internalRead(Class type, Class elementType, JsonValue jsonData, Class keyType){ + private T internalRead(Class type, Class elementType, JsonValue jsonData, Class keyType){ if(type != null){ if(classParsers.containsKey(type)){ try{ @@ -114,6 +114,29 @@ public class ContentParser{ } } + //try to parse "item/amount" syntax + try{ + if(type == ItemStack.class && jsonData.isString() && jsonData.asString().contains("/")){ + String[] split = jsonData.asString().split("/"); + + return (T)fromJson(ItemStack.class, "{item: " + split[0] + ", amount: " + split[1] + "}"); + } + }catch(Throwable ignored){ + } + + //try to parse "liquid/amount" syntax + try{ + if(jsonData.isString() && jsonData.asString().contains("/")){ + String[] split = jsonData.asString().split("/"); + if(type == LiquidStack.class){ + return (T)fromJson(LiquidStack.class, "{liquid: " + split[0] + ", amount: " + split[1] + "}"); + }else if(type == ConsumeLiquid.class){ + return (T)fromJson(ConsumeLiquid.class, "{liquid: " + split[0] + ", amount: " + split[1] + "}"); + } + } + }catch(Throwable ignored){ + } + if(Content.class.isAssignableFrom(type)){ ContentType ctype = contentTypes.getThrow(type, () -> new IllegalArgumentException("No content type for class: " + type.getSimpleName())); String prefix = currentMod != null ? currentMod.name + "-" : ""; @@ -342,7 +365,22 @@ public class ContentParser{ init(); } - JsonValue value = parser.fromJson(null, Jval.read(json).toString(Jformat.plain)); + JsonValue value; + try{ + //try to read hjson, bail out if it doesn't work + value = parser.fromJson(null, Jval.read(json).toString(Jformat.plain)); + }catch(Throwable t){ + try{ + value = parser.fromJson(null, json); + }catch(Throwable extra){ + if(t instanceof RuntimeException){ + throw t; + }else{ + throw new RuntimeException(t); + } + } + } + if(!parsers.containsKey(type)){ throw new SerializationException("No parsers for content type '" + type + "'"); } diff --git a/core/src/io/anuke/mindustry/mod/Mods.java b/core/src/io/anuke/mindustry/mod/Mods.java index 59347e01ab..da677a82be 100644 --- a/core/src/io/anuke/mindustry/mod/Mods.java +++ b/core/src/io/anuke/mindustry/mod/Mods.java @@ -14,6 +14,7 @@ import io.anuke.arc.util.ArcAnnotate.*; import io.anuke.arc.util.*; import io.anuke.arc.util.io.*; import io.anuke.arc.util.serialization.*; +import io.anuke.arc.util.serialization.Jval.*; import io.anuke.mindustry.core.*; import io.anuke.mindustry.ctype.*; import io.anuke.mindustry.game.EventType.*; @@ -172,8 +173,7 @@ public class Mods implements Loadable{ /** Loads all mods from the folder, but does not call any methods on them.*/ public void load(){ for(FileHandle file : modDirectory.list()){ - if(!file.extension().equals("jar") && !file.extension().equals("zip") && !(file.isDirectory() && file.child("mod.json").exists())) continue; - + if(!file.extension().equals("jar") && !file.extension().equals("zip") && !(file.isDirectory() && (file.child("mod.json").exists() || file.child("mod.js").exists()))) continue; Log.debug("[Mods] Loading mod {0}", file); try{ @@ -482,13 +482,22 @@ public class Mods implements Loadable{ zip = zip.list()[0]; } - FileHandle metaf = zip.child("mod.json").exists() ? zip.child("mod.json") : zip.child("plugin.json"); + FileHandle metaf = zip.child("mod.json").exists() ? zip.child("mod.json") : zip.child("mod.js").exists() ? zip.child("mod.js") : zip.child("plugin.json"); if(!metaf.exists()){ Log.warn("Mod {0} doesn't have a 'mod.json'/'plugin.json' file, skipping.", sourceFile); throw new IllegalArgumentException("No mod.json found."); } - ModMeta meta = json.fromJson(ModMeta.class, metaf.readString()); + //try to read as hjson if possible + String readString = metaf.readString(); + try{ + readString = Jval.read(readString).toString(Jformat.plain); + }catch(Throwable e){ + e.printStackTrace(); + readString = metaf.readString(); + } + + ModMeta meta = json.fromJson(ModMeta.class, readString); String camelized = meta.name.replace(" ", ""); String mainClass = meta.main == null ? camelized.toLowerCase() + "." + camelized + "Mod" : meta.main; String baseName = meta.name.toLowerCase().replace(" ", "-"); diff --git a/desktop/src/io/anuke/mindustry/desktop/steam/SWorkshop.java b/desktop/src/io/anuke/mindustry/desktop/steam/SWorkshop.java index 170e014a18..03d6ffe37b 100644 --- a/desktop/src/io/anuke/mindustry/desktop/steam/SWorkshop.java +++ b/desktop/src/io/anuke/mindustry/desktop/steam/SWorkshop.java @@ -39,7 +39,7 @@ public class SWorkshop implements SteamUGCCallback{ workshopFiles.put(Map.class, folders.select(f -> f.list().length == 1 && f.list()[0].extension().equals(mapExtension)).map(f -> f.list()[0])); workshopFiles.put(Schematic.class, folders.select(f -> f.list().length == 1 && f.list()[0].extension().equals(schematicExtension)).map(f -> f.list()[0])); - workshopFiles.put(LoadedMod.class, folders.select(f -> f.child("mod.json").exists())); + workshopFiles.put(LoadedMod.class, folders.select(f -> f.child("mod.json").exists() || f.child("mod.js").exists())); if(!workshopFiles.get(Map.class).isEmpty()){ SAchievement.downloadMapWorkshop.complete(); diff --git a/gradle.properties b/gradle.properties index a7d2f776c4..cd20e76ae5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=e9f5ea632c36a9890d6a96c7e9f1cef62ad92b54 +archash=