From f091256edb96c355bde22716dfb38877aee04741 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Thu, 5 Aug 2021 21:24:52 -0400 Subject: [PATCH] Wow --- .../com/volmit/iris/core/WandManager.java | 17 ++---- .../object/CommandIrisObjectPasteMatter.java | 4 +- .../object/CommandIrisObjectSaveMatter.java | 3 +- .../iris/core/nms/v1X/NMSBinding1X.java | 27 +++++++++ .../iris/util/hunk/storage/MappedHunk.java | 16 +++++ .../com/volmit/iris/util/matter/Matter.java | 55 +++++++++++++++--- .../volmit/iris/util/matter/MatterSlice.java | 23 ++++---- .../volmit/iris/util/matter/WorldMatter.java | 58 +++++++++++++++++++ .../iris/util/matter/slices/EntityMatter.java | 23 ++++---- .../iris/util/matter/slices/RawMatter.java | 16 ++--- .../iris/util/matter/slices/TileMatter.java | 8 +-- 11 files changed, 191 insertions(+), 59 deletions(-) create mode 100644 src/main/java/com/volmit/iris/util/matter/WorldMatter.java diff --git a/src/main/java/com/volmit/iris/core/WandManager.java b/src/main/java/com/volmit/iris/core/WandManager.java index e0d6ec14d..10516d71d 100644 --- a/src/main/java/com/volmit/iris/core/WandManager.java +++ b/src/main/java/com/volmit/iris/core/WandManager.java @@ -26,6 +26,8 @@ import com.volmit.iris.util.data.Cuboid; import com.volmit.iris.util.format.C; import com.volmit.iris.util.math.M; import com.volmit.iris.util.matter.IrisMatter; +import com.volmit.iris.util.matter.Matter; +import com.volmit.iris.util.matter.WorldMatter; import com.volmit.iris.util.plugin.VolmitSender; import org.bukkit.*; import org.bukkit.block.Block; @@ -232,26 +234,15 @@ public class WandManager implements Listener { * @param wand The wand itemstack * @return The new object */ - public static IrisMatter createSchematic(Player p, ItemStack wand) { + public static Matter createMatterSchem(Player p, ItemStack wand) { if (!isWand(wand)) { return null; } try { Location[] f = getCuboid(wand); - Cuboid c = new Cuboid(f[0], f[1]); - IrisMatter s = new IrisMatter(c.getSizeX(), c.getSizeY(), c.getSizeZ()); - Iris.info(s.getWidth() + " " + s.getHeight() + " " + s.getDepth()); - s.getHeader().setAuthor(p.getName()); - s.slice(BlockData.class) - .readFrom(c.getWorld(), - c.getLowerNE().getBlockX(), - c.getLowerNE().getBlockY(), c.getLowerNE().getBlockZ()); - Iris.info("Slices: " + s.getSliceMap().size()); - Iris.info("Entries " + s.getSlice(BlockData.class).getCount()); - - return s; + return WorldMatter.createMatter(p.getName(), f[0], f[1]); } catch (Throwable e) { e.printStackTrace(); Iris.reportError(e); diff --git a/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectPasteMatter.java b/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectPasteMatter.java index f27a02be4..7ea69c409 100644 --- a/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectPasteMatter.java +++ b/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectPasteMatter.java @@ -26,6 +26,7 @@ import com.volmit.iris.engine.object.common.IObjectPlacer; import com.volmit.iris.engine.object.tile.TileData; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.matter.Matter; +import com.volmit.iris.util.matter.WorldMatter; import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.VolmitSender; import org.bukkit.HeightMap; @@ -84,8 +85,7 @@ public class CommandIrisObjectPasteMatter extends MortarCommand { File f = new File(args[0]); try { Matter matter = Matter.read(f); - matter.slice(BlockData.class) - .writeInto(p.getWorld(), p.getLocation().getBlockX(), p.getLocation().getBlockY(), p.getLocation().getBlockZ()); + WorldMatter.placeMatter(matter, p.getLocation()); } catch (Throwable e) { e.printStackTrace(); } diff --git a/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectSaveMatter.java b/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectSaveMatter.java index 4be6b4287..f574178fc 100644 --- a/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectSaveMatter.java +++ b/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectSaveMatter.java @@ -23,6 +23,7 @@ import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.WandManager; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.matter.IrisMatter; +import com.volmit.iris.util.matter.Matter; import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.VolmitSender; import org.bukkit.Sound; @@ -75,7 +76,7 @@ public class CommandIrisObjectSaveMatter extends MortarCommand { Player p = sender.player(); ItemStack wand = p.getInventory().getItemInMainHand(); - IrisMatter o = WandManager.createSchematic(p, wand); + Matter o = WandManager.createMatterSchem(p, wand); File file = Iris.proj.getWorkspaceFile(args[0], "objects", args[1] + ".iob"); if (file.exists()) { diff --git a/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java b/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java index 3f0af2307..e0f8b0f99 100644 --- a/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java +++ b/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java @@ -19,9 +19,11 @@ package com.volmit.iris.core.nms.v1X; import com.volmit.iris.core.nms.INMSBinding; +import com.volmit.iris.util.nbt.tag.CompoundTag; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.block.Biome; +import org.bukkit.entity.Entity; import org.bukkit.generator.ChunkGenerator; public class NMSBinding1X implements INMSBinding { @@ -42,6 +44,31 @@ public class NMSBinding1X implements INMSBinding { return false; } + @Override + public boolean hasTile(Location l) { + return false; + } + + @Override + public CompoundTag serializeTile(Location location) { + return null; + } + + @Override + public void deserializeTile(CompoundTag s, Location newPosition) { + + } + + @Override + public CompoundTag serializeEntity(Entity location) { + return null; + } + + @Override + public Entity deserializeEntity(CompoundTag s, Location newPosition) { + return null; + } + @Override public boolean supportsCustomHeight() { return supportsCustomHeight; diff --git a/src/main/java/com/volmit/iris/util/hunk/storage/MappedHunk.java b/src/main/java/com/volmit/iris/util/hunk/storage/MappedHunk.java index 2dbe22658..dc50bb27a 100644 --- a/src/main/java/com/volmit/iris/util/hunk/storage/MappedHunk.java +++ b/src/main/java/com/volmit/iris/util/hunk/storage/MappedHunk.java @@ -20,10 +20,12 @@ package com.volmit.iris.util.hunk.storage; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.function.Consumer4; +import com.volmit.iris.util.function.Consumer4IO; import com.volmit.iris.util.hunk.Hunk; import lombok.Data; import lombok.EqualsAndHashCode; +import java.io.IOException; import java.util.Map; @SuppressWarnings({"DefaultAnnotationParam", "Lombok"}) @@ -69,6 +71,20 @@ public class MappedHunk extends StorageHunk implements Hunk { return this; } + @Override + public synchronized Hunk iterateSyncIO(Consumer4IO c) throws IOException { + int idx, z; + + for (Map.Entry g : data.entrySet()) { + idx = g.getKey(); + z = idx / (getWidth() * getHeight()); + idx -= (z * getWidth() * getHeight()); + c.accept(idx % getWidth(), idx / getWidth(), z, g.getValue()); + } + + return this; + } + @Override public void empty(T b) { data.clear(); diff --git a/src/main/java/com/volmit/iris/util/matter/Matter.java b/src/main/java/com/volmit/iris/util/matter/Matter.java index bd05891de..7f0e701c3 100644 --- a/src/main/java/com/volmit/iris/util/matter/Matter.java +++ b/src/main/java/com/volmit/iris/util/matter/Matter.java @@ -19,6 +19,7 @@ package com.volmit.iris.util.matter; import com.volmit.iris.engine.object.basic.IrisPosition; +import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.data.Varint; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.math.BlockPosition; @@ -240,6 +241,35 @@ public interface Matter { gzo.close(); } + /** + * Remove any slices that are empty + */ + default void trimSlices() + { + Set> drop = null; + + for(Class i : getSliceTypes()) + { + if(getSlice(i).getCount() == 0) + { + if(drop == null) + { + drop = new KSet<>(); + } + + drop.add(i); + } + } + + if(drop != null) + { + for(Class i : drop) + { + deleteSlice(i); + } + } + } + /** * Writes the data to the output stream. The data will be flushed to the provided output * stream however the provided stream will NOT BE CLOSED, so be sure to actually close it @@ -248,12 +278,12 @@ public interface Matter { * @throws IOException shit happens yo */ default void write(OutputStream out) throws IOException { + trimSlices(); DataOutputStream dos = new DataOutputStream(out); - // Write size Varint.writeUnsignedVarInt(getWidth(), dos); Varint.writeUnsignedVarInt(getHeight(), dos); Varint.writeUnsignedVarInt(getDepth(), dos); - dos.writeByte(getSliceTypes().size() + Byte.MIN_VALUE); + dos.writeByte(getSliceTypes().size()); getHeader().write(dos); for (Class i : getSliceTypes()) { @@ -286,19 +316,28 @@ public interface Matter { */ static Matter read(InputStream in, Function matterFactory) throws IOException, ClassNotFoundException { DataInputStream din = new DataInputStream(in); - // Read size into new matter object Matter matter = matterFactory.apply(new BlockPosition( Varint.readUnsignedVarInt(din), Varint.readUnsignedVarInt(din), Varint.readUnsignedVarInt(din))); - int sliceCount = din.readByte() - Byte.MIN_VALUE; + int sliceCount = din.readByte(); matter.getHeader().read(din); while (sliceCount-- > 0) { - Class type = Class.forName(din.readUTF()); - MatterSlice slice = matter.createSlice(type, matter); - slice.read(din); - matter.putSlice(type, slice); + String cn = din.readUTF(); + try + { + Class type = Class.forName(cn); + MatterSlice slice = matter.createSlice(type, matter); + slice.read(din); + matter.putSlice(type, slice); + } + + catch(Throwable e) + { + e.printStackTrace(); + throw new IOException("Can't read class '" + cn + "' (slice count reverse at " + sliceCount + ")"); + } } return matter; diff --git a/src/main/java/com/volmit/iris/util/matter/MatterSlice.java b/src/main/java/com/volmit/iris/util/matter/MatterSlice.java index 02ba46ea5..27347c870 100644 --- a/src/main/java/com/volmit/iris/util/matter/MatterSlice.java +++ b/src/main/java/com/volmit/iris/util/matter/MatterSlice.java @@ -18,10 +18,12 @@ package com.volmit.iris.util.matter; +import com.volmit.iris.Iris; import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.util.data.Varint; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.hunk.storage.MappedHunk; +import org.bukkit.Location; import org.bukkit.World; import org.bukkit.block.data.BlockData; import org.bukkit.entity.Entity; @@ -55,6 +57,10 @@ public interface MatterSlice extends Hunk { return c; } + default boolean writeInto(Location location) { + return writeInto(location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ()); + } + default boolean writeInto(W w, int x, int y, int z) { MatterWriter injector = (MatterWriter) writeInto(getClass(w)); @@ -62,22 +68,15 @@ public interface MatterSlice extends Hunk { return false; } - for (int i = x; i < x + getWidth(); i++) { - for (int j = y; j < y + getHeight(); j++) { - for (int k = z; k < z + getDepth(); k++) { - T g = get(i - x, j - y, k - z); - - if(g != null) - { - injector.writeMatter(w, g, i, j, k); - } - } - } - } + iterateSync((a,b,c,t) -> injector.writeMatter(w, t, a+x, b+y, c+z)); return true; } + default boolean readFrom(Location location) { + return readFrom(location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ()); + } + default boolean readFrom(W w, int x, int y, int z) { MatterReader ejector = (MatterReader) readFrom(getClass(w)); diff --git a/src/main/java/com/volmit/iris/util/matter/WorldMatter.java b/src/main/java/com/volmit/iris/util/matter/WorldMatter.java new file mode 100644 index 000000000..88b790fdc --- /dev/null +++ b/src/main/java/com/volmit/iris/util/matter/WorldMatter.java @@ -0,0 +1,58 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.matter; + +import com.volmit.iris.Iris; +import com.volmit.iris.util.data.Cuboid; +import org.bukkit.Location; +import org.bukkit.block.data.BlockData; + +public class WorldMatter { + public static void placeMatter(Matter matter, Location at) + { + if(matter.hasSlice(BlockData.class)) + { + matter.slice(BlockData.class).writeInto(at); + } + + if(matter.hasSlice(MatterEntityGroup.class)) + { + matter.slice(MatterEntityGroup.class).writeInto(at); + } + + if(matter.hasSlice(MatterTile.class)) + { + matter.slice(MatterTile.class).writeInto(at); + } + } + + public static Matter createMatter(String author, Location a, Location b) + { + Cuboid c = new Cuboid(a, b); + Matter s = new IrisMatter(c.getSizeX(), c.getSizeY(), c.getSizeZ()); + Iris.info(s.getWidth() + " " + s.getHeight() + " " + s.getDepth()); + s.getHeader().setAuthor(author); + s.slice(BlockData.class).readFrom(c.getLowerNE()); + s.slice(MatterEntityGroup.class).readFrom(c.getLowerNE()); + s.slice(MatterTile.class).readFrom(c.getLowerNE()); + s.trimSlices(); + + return s; + } +} diff --git a/src/main/java/com/volmit/iris/util/matter/slices/EntityMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/EntityMatter.java index f4601096a..48f02db87 100644 --- a/src/main/java/com/volmit/iris/util/matter/slices/EntityMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/slices/EntityMatter.java @@ -18,6 +18,7 @@ package com.volmit.iris.util.matter.slices; +import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.engine.object.basic.IrisPosition; import com.volmit.iris.util.collection.KList; @@ -41,6 +42,10 @@ public class EntityMatter extends RawMatter { public EntityMatter() { this(1, 1, 1); + } + + public EntityMatter(int width, int height, int depth) { + super(width, height, depth, MatterEntityGroup.class); registerWriter(World.class, ((w, d, x, y, z) -> { for(MatterEntity i : d.getEntities()) { @@ -57,10 +62,10 @@ public class EntityMatter extends RawMatter { for(Entity i : entities) { g.getEntities().add(new MatterEntity( - Math.abs(i.getLocation().getX()) - Math.abs(i.getLocation().getBlockX()), - Math.abs(i.getLocation().getY()) - Math.abs(i.getLocation().getBlockY()), - Math.abs(i.getLocation().getZ()) - Math.abs(i.getLocation().getBlockZ()), - INMS.get().serializeEntity(i) + Math.abs(i.getLocation().getX()) - Math.abs(i.getLocation().getBlockX()), + Math.abs(i.getLocation().getY()) - Math.abs(i.getLocation().getBlockY()), + Math.abs(i.getLocation().getZ()) - Math.abs(i.getLocation().getBlockZ()), + INMS.get().serializeEntity(i) )); } @@ -71,10 +76,6 @@ public class EntityMatter extends RawMatter { }); } - public EntityMatter(int width, int height, int depth) { - super(width, height, depth, MatterEntityGroup.class); - } - /** * The readFrom is overridden only if W is a Bukkit World, instead of looping * across every block position, we simply use getNearbyEntities and cache each @@ -94,9 +95,9 @@ public class EntityMatter extends RawMatter { return super.readFrom(w, x, y, z); } - MatterReader ejector = (MatterReader) readFrom(getClass(w)); + MatterReader reader = (MatterReader) readFrom(World.class); - if (ejector == null) { + if (reader == null) { return false; } @@ -110,7 +111,7 @@ public class EntityMatter extends RawMatter { for(IrisPosition i : entityCache.keySet()) { - MatterEntityGroup g = ejector.readMatter(w, i.getX(), i.getY(), i.getZ()); + MatterEntityGroup g = reader.readMatter(w, i.getX(), i.getY(), i.getZ()); if(g != null) { diff --git a/src/main/java/com/volmit/iris/util/matter/slices/RawMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/RawMatter.java index df1f07314..7566f9c91 100644 --- a/src/main/java/com/volmit/iris/util/matter/slices/RawMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/slices/RawMatter.java @@ -32,32 +32,32 @@ import java.io.IOException; public abstract class RawMatter extends MappedHunk implements MatterSlice { @Getter private final Class type; - private final KMap, MatterWriter> injectors; - private final KMap, MatterReader> ejectors; + protected final KMap, MatterWriter> writers; + protected final KMap, MatterReader> readers; public RawMatter(int width, int height, int depth, Class type) { super(width, height, depth); - injectors = new KMap<>(); - ejectors = new KMap<>(); + writers = new KMap<>(); + readers = new KMap<>(); this.type = type; } protected void registerWriter(Class mediumType, MatterWriter injector) { - injectors.put(mediumType, injector); + writers.put(mediumType, injector); } protected void registerReader(Class mediumType, MatterReader injector) { - ejectors.put(mediumType, injector); + readers.put(mediumType, injector); } @Override public MatterWriter writeInto(Class mediumType) { - return (MatterWriter) injectors.get(mediumType); + return (MatterWriter) writers.get(mediumType); } @Override public MatterReader readFrom(Class mediumType) { - return (MatterReader) ejectors.get(mediumType); + return (MatterReader) readers.get(mediumType); } @Override diff --git a/src/main/java/com/volmit/iris/util/matter/slices/TileMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/TileMatter.java index 2db9ab1c2..a4f009c23 100644 --- a/src/main/java/com/volmit/iris/util/matter/slices/TileMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/slices/TileMatter.java @@ -36,6 +36,10 @@ import java.io.IOException; public class TileMatter extends RawMatter { public TileMatter() { this(1, 1, 1); + } + + public TileMatter(int width, int height, int depth) { + super(width, height, depth, MatterTile.class); registerWriter(World.class, ((w, d, x, y, z) -> INMS.get().deserializeTile(d.getTileData(), new Location(w, x, y, z)))); registerReader(World.class, (w, x, y, z) -> { Location l = new Location(w, x, y, z); @@ -53,10 +57,6 @@ public class TileMatter extends RawMatter { }); } - public TileMatter(int width, int height, int depth) { - super(width, height, depth, MatterTile.class); - } - @Override public void writeNode(MatterTile b, DataOutputStream dos) throws IOException { NBTUtil.write(b.getTileData(), dos, false);