diff --git a/docs/scarpet/api/Auxiliary.md b/docs/scarpet/api/Auxiliary.md index 408d103e..0c8db933 100644 --- a/docs/scarpet/api/Auxiliary.md +++ b/docs/scarpet/api/Auxiliary.md @@ -431,7 +431,7 @@ Returns `true` if creation and loading of the datapack was successful. Loading o reloading of all other datapacks (vanilla restrictions, identical to /datapack enable), however unlike with `/reload` command, scarpet apps will not be reloaded by adding a datapack using `create_datapack`. -Currently, only json files are supported in the packs. `'pack.mcmeta'` file is added automatically. +Currently, only json/nbt/mcfunction files are supported in the packs. `'pack.mcmeta'` file is added automatically. Reloading of datapacks that define new dimensions is not implemented in vanilla. Vanilla game only loads dimension information on server start. `create_datapack` is therefore a direct replacement of manually ploping of the specified @@ -548,6 +548,10 @@ script run create_datapack('craftable_cobwebs', { }); +Function example: +
+ script run create_datapack('example',{'data/test/functions/talk.mcfunction'->'say 1\nsay 2'})
+
### `enable_hidden_dimensions()` The function reads current datapack settings detecting new dimensions defined by these datapacks that have not yet been added diff --git a/src/main/java/carpet/script/api/Auxiliary.java b/src/main/java/carpet/script/api/Auxiliary.java index 5e508815..c63bc3ac 100644 --- a/src/main/java/carpet/script/api/Auxiliary.java +++ b/src/main/java/carpet/script/api/Auxiliary.java @@ -29,6 +29,7 @@ import carpet.script.utils.WorldTools; import carpet.script.value.BooleanValue; import carpet.script.value.EntityValue; import carpet.script.value.FormattedTextValue; +import carpet.script.value.LazyListValue; import carpet.script.value.ListValue; import carpet.script.value.MapValue; import carpet.script.value.NBTSerializableValue; @@ -50,6 +51,7 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtHelper; +import net.minecraft.nbt.NbtIo; import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.NbtString; import net.minecraft.nbt.NbtElement; @@ -1180,6 +1182,75 @@ public class Auxiliary { } } } + private static void zipValueToText(Path path, Value output) throws IOException + { + List toJoin; + String string; + String delimiter=System.lineSeparator(); + // i dont know it shoule be \n or System.lineSeparator + if (output instanceof LazyListValue) + { + toJoin = ((LazyListValue) output).unroll(); + string = toJoin.stream().map(Value::getString).collect(Collectors.joining(delimiter)); + } + else if (output instanceof ListValue) + { + toJoin = ((ListValue) output).getItems(); + string = toJoin.stream().map(Value::getString).collect(Collectors.joining(delimiter)); + } + else + { + string = output.getString(); + } + + + Files.createDirectories(path.getParent()); + BufferedWriter bufferedWriter = Files.newBufferedWriter(path); + Throwable incident = null; + try + { + bufferedWriter.write(string); + } + catch (Throwable shitHappened) + { + incident = shitHappened; + throw shitHappened; + } + finally + { + if (incident != null) { + try { + bufferedWriter.close(); + } catch (Throwable otherShitHappened) { + incident.addSuppressed(otherShitHappened); + } + } else { + bufferedWriter.close(); + } + } + } + + private static void zipValueToNBT(Path path, Value output) throws IOException + { + + + NBTSerializableValue tagValue = (output instanceof NBTSerializableValue) + ? (NBTSerializableValue) output + : new NBTSerializableValue(output.getString()); + NbtElement tag = tagValue.getTag(); + Files.createDirectories(path.getParent()); + + + try + { + if (tag instanceof NbtCompound) + NbtIo.writeCompressed((NbtCompound) tag, Files.newOutputStream(path)); + } + catch (Throwable shitHappened) + { + throw shitHappened; + } + } private static void walkTheDPMap(MapValue node, Path path) throws IOException { @@ -1193,7 +1264,13 @@ public class Auxiliary { { zipValueToJson(child, val); } - else + else if (strkey.endsWith(".mcfunction")|strkey.endsWith(".txt")|strkey.endsWith(".mcmeta")) + { + zipValueToText(child, val); + }else if (strkey.endsWith(".nbt")) + { + zipValueToNBT(child, val); + }else { if (!(val instanceof MapValue)) throw new InternalExpressionException("Value of "+strkey+" should be a map"); Files.createDirectory(child);