From 803dfed9f7765c0b6f04e61ee1ca9c119c36a431 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sat, 7 Aug 2021 02:48:36 -0400 Subject: [PATCH] Mantle & Debugging --- src/main/java/com/volmit/iris/Iris.java | 36 +++++- .../com/volmit/iris/engine/IrisEngine.java | 16 +-- .../iris/engine/parallax/ParallaxWorld.java | 2 + .../java/com/volmit/iris/util/hunk/Hunk.java | 47 ++++++++ .../volmit/iris/util/hunk/HunkFactory.java | 24 ++++ .../iris/util/hunk/storage/ArrayHunk.java | 1 + .../iris/util/hunk/storage/MappedHunk.java | 4 + .../com/volmit/iris/util/mantle/Mantle.java | 107 +++++++++++++++++ .../volmit/iris/util/mantle/MantleChunk.java | 112 ++++++++++++++++++ .../volmit/iris/util/mantle/MantleMatter.java | 69 +++++++++++ .../volmit/iris/util/mantle/MantleRegion.java | 107 +++++++++++++++++ .../util/mantle/slices/MantleBlockMatter.java | 59 +++++++++ .../util/mantle/slices/RawMantleMatter.java | 70 +++++++++++ .../com/volmit/iris/util/matter/Matter.java | 14 ++- .../volmit/iris/util/matter/MatterSlice.java | 47 +++++--- .../iris/util/matter/slices/BlockMatter.java | 2 - 16 files changed, 675 insertions(+), 42 deletions(-) create mode 100644 src/main/java/com/volmit/iris/util/hunk/HunkFactory.java create mode 100644 src/main/java/com/volmit/iris/util/mantle/Mantle.java create mode 100644 src/main/java/com/volmit/iris/util/mantle/MantleChunk.java create mode 100644 src/main/java/com/volmit/iris/util/mantle/MantleMatter.java create mode 100644 src/main/java/com/volmit/iris/util/mantle/MantleRegion.java create mode 100644 src/main/java/com/volmit/iris/util/mantle/slices/MantleBlockMatter.java create mode 100644 src/main/java/com/volmit/iris/util/mantle/slices/RawMantleMatter.java diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index 59cb7302e..32d9f80ab 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -524,7 +524,41 @@ public class Iris extends VolmitPlugin implements Listener { return; } - msg(C.LIGHT_PURPLE + string); + try + { + throw new RuntimeException(); + } + + catch(Throwable e) + { + try + { + String[] cc = e.getStackTrace()[1].getClassName().split("\\Q.\\E"); + + if(cc.length > 5) + { + debug(cc[3] + "/" + cc[4] + "/" + cc[cc.length-1], e.getStackTrace()[1].getLineNumber(), string); + } + + else + { + debug(cc[3] + "/" + cc[4], e.getStackTrace()[1].getLineNumber(), string); + } + } + + catch(Throwable ex) + { + debug("Origin", -1, string); + } + } + } + + public static void debug(String category, int line, String string) { + if (!IrisSettings.get().getGeneral().isDebug()) { + return; + } + + msg("" + category + " <#bf3b76>" + line + " " + C.LIGHT_PURPLE + string.replaceAll("\\Q<\\E", "[").replaceAll("\\Q>\\E", "]")); } public static void verbose(String string) { diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index bf41850d0..a04883b4f 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -228,24 +228,10 @@ public class IrisEngine extends BlockPopulator implements Engine { } case ISLANDS -> { getFramework().getTerrainActuator().actuate(x, z, vblocks, multicore); - } } getMetrics().getTotal().put(p.getMilliseconds()); - - if (IrisSettings.get().getGeneral().isDebug()) { - KList v = new KList<>(); - KMap g = getMetrics().pull(); - - for (String i : g.sortKNumber()) { - if (g.get(i) != null) { - v.add(C.RESET + "" + C.LIGHT_PURPLE + i + ": " + C.UNDERLINE + C.BLUE + Form.duration(g.get(i), 0) + C.RESET + C.GRAY + ""); - } - } - - Iris.debug(v.toString(", ")); - } } catch (Throwable e) { Iris.reportError(e); fail("Failed to generate " + x + ", " + z, e); @@ -258,7 +244,9 @@ public class IrisEngine extends BlockPopulator implements Engine { f.getParentFile().mkdirs(); try { IO.writeAll(f, new Gson().toJson(getEngineData())); + Iris.debug("Saved Engine Data"); } catch (IOException e) { + Iris.error("Failed to save Engine Data"); e.printStackTrace(); } } diff --git a/src/main/java/com/volmit/iris/engine/parallax/ParallaxWorld.java b/src/main/java/com/volmit/iris/engine/parallax/ParallaxWorld.java index 332d2c903..a8892ecab 100644 --- a/src/main/java/com/volmit/iris/engine/parallax/ParallaxWorld.java +++ b/src/main/java/com/volmit/iris/engine/parallax/ParallaxWorld.java @@ -114,6 +114,7 @@ public class ParallaxWorld implements ParallaxAccess { if (lr != null) { v += lr.unload(); + Iris.debug("Unloaded Parallax Region " + C.RED + x + " " + z); } } @@ -128,6 +129,7 @@ public class ParallaxWorld implements ParallaxAccess { ParallaxRegion v = new ParallaxRegion(burst, height, folder, x, z); loadedRegions.put(key(x, z), v); + Iris.debug("Loaded Parallax Region " + C.RED + x + " " + z); return v; } diff --git a/src/main/java/com/volmit/iris/util/hunk/Hunk.java b/src/main/java/com/volmit/iris/util/hunk/Hunk.java index 2dc3d8b4a..6695535e5 100644 --- a/src/main/java/com/volmit/iris/util/hunk/Hunk.java +++ b/src/main/java/com/volmit/iris/util/hunk/Hunk.java @@ -61,6 +61,14 @@ public interface Hunk { return new HunkView(src); } + default boolean isMapped() { + return false; + } + + default int getEntryCount() { + return getWidth() * getHeight() * getDepth(); + } + static Hunk convertedReadView(Hunk src, Function reader) { return new FunctionalHunkView(src, reader, null); } @@ -1059,6 +1067,45 @@ public interface Hunk { setRaw(x, y, z, t); } + /** + * Create a hunk that is optimized for specific uses + * @param w width + * @param h height + * @param d depth + * @param type the class type + * @param packed if the hunk is generally more than 50% full (non-null nodes) + * @param concurrent if this hunk must be thread safe + * @param the type + * @return the hunk + */ + static Hunk newHunk(int w, int h, int d, Class type, boolean packed, boolean concurrent) + { + if(type.equals(Double.class)) + { + return concurrent ? + packed ? (Hunk) newAtomicDoubleHunk(w,h,d) : newMappedHunk(w,h,d) + : packed ? newArrayHunk(w,h,d) : newMappedHunkSynced(w,h,d); + } + + if(type.equals(Integer.class)) + { + return concurrent ? + packed ? (Hunk) newAtomicIntegerHunk(w,h,d) : newMappedHunk(w,h,d) + : packed ? newArrayHunk(w,h,d) : newMappedHunkSynced(w,h,d); + } + + if(type.equals(Long.class)) + { + return concurrent ? + packed ? (Hunk) newAtomicLongHunk(w,h,d) : newMappedHunk(w,h,d) + : packed ? newArrayHunk(w,h,d) : newMappedHunkSynced(w,h,d); + } + + return concurrent ? + packed ? newAtomicHunk(w,h,d) : newMappedHunk(w,h,d) + : packed ? newArrayHunk(w,h,d) : newMappedHunkSynced(w,h,d); + } + default void setIfExists(int x, int y, int z, T t) { if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight() || z < 0 || z >= getDepth()) { return; diff --git a/src/main/java/com/volmit/iris/util/hunk/HunkFactory.java b/src/main/java/com/volmit/iris/util/hunk/HunkFactory.java new file mode 100644 index 000000000..e7ed21135 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/hunk/HunkFactory.java @@ -0,0 +1,24 @@ +/* + * 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.hunk; + +@FunctionalInterface +public interface HunkFactory { + Hunk create(int w, int h, int d); +} diff --git a/src/main/java/com/volmit/iris/util/hunk/storage/ArrayHunk.java b/src/main/java/com/volmit/iris/util/hunk/storage/ArrayHunk.java index 48d17a70c..4512ba9a8 100644 --- a/src/main/java/com/volmit/iris/util/hunk/storage/ArrayHunk.java +++ b/src/main/java/com/volmit/iris/util/hunk/storage/ArrayHunk.java @@ -20,6 +20,7 @@ package com.volmit.iris.util.hunk.storage; import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.util.hunk.Hunk; +import com.volmit.iris.util.hunk.HunkFactory; import lombok.Data; import lombok.EqualsAndHashCode; 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 9d0d30f02..7cbe52f0a 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 @@ -43,6 +43,10 @@ public class MappedHunk extends StorageHunk implements Hunk { return data.size(); } + public boolean isMapped() { + return true; + } + public boolean isEmpty() { return data.isEmpty(); diff --git a/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/src/main/java/com/volmit/iris/util/mantle/Mantle.java new file mode 100644 index 000000000..860c092ad --- /dev/null +++ b/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -0,0 +1,107 @@ +/* + * 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.mantle; + +import com.volmit.iris.Iris; +import com.volmit.iris.engine.data.cache.Cache; +import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.documentation.RegionCoordinates; +import com.volmit.iris.util.format.C; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.Map; + +public class Mantle +{ + private final File dataFolder; + private final int worldHeight; + private final Map loadedRegions; + + public Mantle(File dataFolder, int worldHeight) + { + this.dataFolder = dataFolder; + this.worldHeight = worldHeight; + dataFolder.mkdirs(); + loadedRegions = new KMap<>(); + } + + @RegionCoordinates + public MantleRegion get(int x, int z) + { + Long k = key(x, z); + MantleRegion region = loadedRegions.get(k); + + if(region != null) + { + return region; + } + + synchronized (loadedRegions) + { + // Ensure we are the first loading thread + region = loadedRegions.get(k); + + if(region != null) + { + return region; + } + + File file = fileForRegion(x, z); + + if(file.exists()) + { + try + { + FileInputStream fin = new FileInputStream(file); + DataInputStream din = new DataInputStream(fin); + region = new MantleRegion(worldHeight, din); + din.close(); + Iris.debug("Loaded Mantle Region " + C.RED + x + " " + z + C.DARK_AQUA + " " + file.getName()); + } + + catch(Throwable e) + { + Iris.error("Failed to read Mantle Region " + file.getAbsolutePath() + " creating a new chunk instead."); + Iris.reportError(e); + e.printStackTrace(); + region = null; + } + } + + if(region != null) + { + return region; + } + + Iris.debug("Created new Mantle Region " + C.RED + x + " " + z); + return new MantleRegion(worldHeight); + } + } + + private File fileForRegion(int x, int z) { + return new File("m." + x + "." + z + ".mtl"); + } + + public Long key(int x, int z) + { + return Cache.key(x, z); + } +} diff --git a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java new file mode 100644 index 000000000..d629f6245 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java @@ -0,0 +1,112 @@ +/* + * 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.mantle; + +import com.volmit.iris.engine.data.chunk.MCATerrainChunk; +import com.volmit.iris.util.data.Varint; +import com.volmit.iris.util.documentation.ChunkCoordinates; +import com.volmit.iris.util.nbt.mca.Section; +import lombok.Data; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.concurrent.atomic.AtomicReferenceArray; + +public class MantleChunk { + private final AtomicReferenceArray sections; + + @ChunkCoordinates + public MantleChunk(int sectionHeight) + { + sections = new AtomicReferenceArray<>(sectionHeight); + } + + public MantleChunk(int sectionHeight, DataInputStream din) throws IOException, ClassNotFoundException { + this(sectionHeight); + int s = Varint.readUnsignedVarInt(din); + + for(int i = 0; i < s; i++) + { + if(din.readBoolean()) + { + sections.set(i, MantleMatter.read(din)); + } + } + } + + @ChunkCoordinates + public boolean exists(int section) + { + return get(section) != null; + } + + @ChunkCoordinates + public MantleMatter get(int section) + { + return sections.get(section); + } + + public void clear() + { + for(int i = 0; i < sections.length(); i++) + { + delete(i); + } + } + + @ChunkCoordinates + public void delete(int section) + { + sections.set(section, null); + } + + @ChunkCoordinates + public MantleMatter getOrCreate(int section) + { + MantleMatter matter = get(section); + + if(matter == null) + { + matter = new MantleMatter(16, 16, 16); + sections.set(section, matter); + } + + return matter; + } + + public void write(DataOutputStream dos) throws IOException { + Varint.writeUnsignedVarInt(sections.length(), dos); + + for(int i = 0; i < sections.length(); i++) + { + if(exists(i)) + { + dos.writeBoolean(true); + MantleMatter matter = get(i); + matter.writeDos(dos); + } + + else + { + dos.writeBoolean(false); + } + } + } +} diff --git a/src/main/java/com/volmit/iris/util/mantle/MantleMatter.java b/src/main/java/com/volmit/iris/util/mantle/MantleMatter.java new file mode 100644 index 000000000..8ef6d6108 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/mantle/MantleMatter.java @@ -0,0 +1,69 @@ +/* + * 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.mantle; + +import com.volmit.iris.Iris; +import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.matter.IrisMatter; +import com.volmit.iris.util.matter.Matter; +import com.volmit.iris.util.matter.MatterSlice; +import com.volmit.iris.util.matter.Sliced; + +import java.io.DataInputStream; +import java.io.IOException; + +public class MantleMatter extends IrisMatter +{ + protected static final KMap, MatterSlice> slicers = buildSlicers(); + + public MantleMatter(int width, int height, int depth) { + super(width, height, depth); + } + + public static MantleMatter read(DataInputStream din) throws IOException, ClassNotFoundException { + return (MantleMatter) Matter.read(din, (b) -> new MantleMatter(b.getX(), b.getY(), b.getZ())); + } + + @Override + public MatterSlice createSlice(Class type, Matter m) { + MatterSlice slice = slicers.get(type); + + if (slice == null) { + return null; + } + + try { + return slice.getClass().getConstructor(int.class, int.class, int.class).newInstance(getWidth(), getHeight(), getDepth()); + } catch (Throwable e) { + e.printStackTrace(); + } + + return null; + } + + private static KMap, MatterSlice> buildSlicers() { + KMap, MatterSlice> c = new KMap<>(); + for (Object i : Iris.initialize("com.volmit.iris.util.mantle.slices", Sliced.class)) { + MatterSlice s = (MatterSlice) i; + c.put(s.getType(), s); + } + + return c; + } +} diff --git a/src/main/java/com/volmit/iris/util/mantle/MantleRegion.java b/src/main/java/com/volmit/iris/util/mantle/MantleRegion.java new file mode 100644 index 000000000..689de0ffa --- /dev/null +++ b/src/main/java/com/volmit/iris/util/mantle/MantleRegion.java @@ -0,0 +1,107 @@ +/* + * 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.mantle; + +import com.volmit.iris.util.documentation.ChunkCoordinates; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.concurrent.atomic.AtomicReferenceArray; + +public class MantleRegion { + private final int sectionHeight; + private final AtomicReferenceArray chunks; + + public MantleRegion(int worldHeight) + { + this.sectionHeight = worldHeight >> 4; + this.chunks = new AtomicReferenceArray<>(1024); + } + + public MantleRegion(int worldHeight, DataInputStream din) throws IOException, ClassNotFoundException { + this(worldHeight); + + for(int i = 0; i < chunks.length(); i++) + { + if(din.readBoolean()) + { + chunks.set(i, new MantleChunk(sectionHeight, din)); + } + } + } + + @ChunkCoordinates + public boolean exists(int x, int z) + { + return get(x, z) != null; + } + + @ChunkCoordinates + public MantleChunk get(int x, int z) + { + return chunks.get(index(x, z)); + } + + public void clear() + { + for(int i = 0; i < chunks.length(); i++) + { + chunks.set(i, null); + } + } + + @ChunkCoordinates + public void delete(int x, int z) + { + chunks.set(index(x, z), null); + } + + @ChunkCoordinates + public MantleChunk getOrCreate(int x, int z) + { + MantleChunk chunk = get(x, z); + + if(chunk == null) + { + chunk = new MantleChunk(sectionHeight); + chunks.set(index(x, z), chunk); + } + + return chunk; + } + + @ChunkCoordinates + private int index(int x, int z) { + return (x & 0x1F) + (z & 0x1F) * 32; + } + + public void write(DataOutputStream dos) throws IOException { + for(int i = 0; i < chunks.length(); i++) + { + MantleChunk chunk = chunks.get(i); + dos.writeBoolean(chunk != null); + + if(chunk != null) + { + chunk.write(dos); + } + } + } +} diff --git a/src/main/java/com/volmit/iris/util/mantle/slices/MantleBlockMatter.java b/src/main/java/com/volmit/iris/util/mantle/slices/MantleBlockMatter.java new file mode 100644 index 000000000..4bcac872c --- /dev/null +++ b/src/main/java/com/volmit/iris/util/mantle/slices/MantleBlockMatter.java @@ -0,0 +1,59 @@ +/* + * 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.mantle.slices; + +import com.volmit.iris.engine.parallax.ParallaxAccess; +import com.volmit.iris.engine.parallax.ParallaxWorld; +import com.volmit.iris.util.data.B; +import com.volmit.iris.util.matter.Sliced; +import com.volmit.iris.util.matter.slices.RawMatter; +import org.bukkit.World; +import org.bukkit.block.data.BlockData; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +@Sliced +public class MantleBlockMatter extends RawMatter { + public MantleBlockMatter() { + this(1, 1, 1); + } + + public MantleBlockMatter(int width, int height, int depth) { + super(width, height, depth, BlockData.class); + registerWriter(World.class, ((w, d, x, y, z) -> w.getBlockAt(x, y, z).setBlockData(d))); + registerWriter(ParallaxWorld.class, (w, d, x, y, z) -> w.setBlock(x, y, z, d)); + registerReader(World.class, (w, x, y, z) -> { + BlockData d = w.getBlockAt(x, y, z).getBlockData(); + return d.getMaterial().isAir() ? null : d; + }); + registerReader(ParallaxWorld.class, ParallaxAccess::getBlock); + } + + @Override + public void writeNode(BlockData b, DataOutputStream dos) throws IOException { + dos.writeUTF(b.getAsString(true)); + } + + @Override + public BlockData readNode(DataInputStream din) throws IOException { + return B.get(din.readUTF()); + } +} diff --git a/src/main/java/com/volmit/iris/util/mantle/slices/RawMantleMatter.java b/src/main/java/com/volmit/iris/util/mantle/slices/RawMantleMatter.java new file mode 100644 index 000000000..d8f711a0c --- /dev/null +++ b/src/main/java/com/volmit/iris/util/mantle/slices/RawMantleMatter.java @@ -0,0 +1,70 @@ +/* + * 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.mantle.slices; + +import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.hunk.storage.ArrayHunk; +import com.volmit.iris.util.hunk.storage.AtomicHunk; +import com.volmit.iris.util.hunk.storage.MappedHunk; +import com.volmit.iris.util.matter.MatterReader; +import com.volmit.iris.util.matter.MatterSlice; +import com.volmit.iris.util.matter.MatterWriter; +import lombok.Getter; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public abstract class RawMantleMatter extends AtomicHunk implements MatterSlice { + @Getter + private final Class type; + protected final KMap, MatterWriter> writers; + protected final KMap, MatterReader> readers; + + public RawMantleMatter(int width, int height, int depth, Class type) { + super(width, height, depth); + writers = new KMap<>(); + readers = new KMap<>(); + this.type = type; + } + + protected void registerWriter(Class mediumType, MatterWriter injector) { + writers.put(mediumType, injector); + } + + protected void registerReader(Class mediumType, MatterReader injector) { + readers.put(mediumType, injector); + } + + @Override + public MatterWriter writeInto(Class mediumType) { + return (MatterWriter) writers.get(mediumType); + } + + @Override + public MatterReader readFrom(Class mediumType) { + return (MatterReader) readers.get(mediumType); + } + + @Override + public abstract void writeNode(T b, DataOutputStream dos) throws IOException; + + @Override + public abstract T readNode(DataInputStream din) throws IOException; +} 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 4edea9dba..63d4cd66b 100644 --- a/src/main/java/com/volmit/iris/util/matter/Matter.java +++ b/src/main/java/com/volmit/iris/util/matter/Matter.java @@ -24,6 +24,7 @@ import com.volmit.iris.util.data.Varint; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.math.BlockPosition; +import javax.xml.crypto.Data; import java.io.*; import java.util.Map; import java.util.Set; @@ -87,7 +88,7 @@ public interface Matter { } /** - * Create a slice from the given type + * Create a slice from the given type (full is false) * * @param type the type class * @param matter the matter this slice will go into (size provider) @@ -248,7 +249,7 @@ public interface Matter { Set> drop = null; for (Class i : getSliceTypes()) { - if (getSlice(i).getCount() == 0) { + if (getSlice(i).getEntryCount() == 0) { if (drop == null) { drop = new KSet<>(); } @@ -272,8 +273,11 @@ public interface Matter { * @throws IOException shit happens yo */ default void write(OutputStream out) throws IOException { + writeDos(new DataOutputStream(out)); + } + + default void writeDos(DataOutputStream dos) throws IOException { trimSlices(); - DataOutputStream dos = new DataOutputStream(out); Varint.writeUnsignedVarInt(getWidth(), dos); Varint.writeUnsignedVarInt(getHeight(), dos); Varint.writeUnsignedVarInt(getDepth(), dos); @@ -283,8 +287,6 @@ public interface Matter { for (Class i : getSliceTypes()) { getSlice(i).write(dos); } - - dos.flush(); } static Matter read(File f) throws IOException, ClassNotFoundException { @@ -339,7 +341,7 @@ public interface Matter { for(MatterSlice i : getSliceMap().values()) { - m+= i.getCount(); + m+= i.getEntryCount(); } return m; 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 079daa412..cc7a57508 100644 --- a/src/main/java/com/volmit/iris/util/matter/MatterSlice.java +++ b/src/main/java/com/volmit/iris/util/matter/MatterSlice.java @@ -99,14 +99,6 @@ public interface MatterSlice extends Hunk { return true; } - // BlockMatter - // RawMatter ex MappedHunk - // IMatterSlice ex Hunk - - default int getCount() { - return ((MappedHunk) this).getEntryCount(); - } - default boolean canWrite(Class mediumType) { return writeInto(mediumType) != null; } @@ -122,24 +114,41 @@ public interface MatterSlice extends Hunk { MatterPalette palette = new MatterPalette(this); iterateSync((x, y, z, b) -> palette.assign(b)); palette.writePalette(dos); - Varint.writeUnsignedVarInt(getCount(), dos); - iterateSyncIO((x, y, z, b) -> { - Varint.writeUnsignedVarInt(Cache.to1D(x, y, z, w, h), dos); - palette.writeNode(b, dos); - }); + dos.writeBoolean(isMapped()); + + if(isMapped()) + { + Varint.writeUnsignedVarInt(getEntryCount(), dos); + iterateSyncIO((x, y, z, b) -> { + Varint.writeUnsignedVarInt(Cache.to1D(x, y, z, w, h), dos); + palette.writeNode(b, dos); + }); + } + + else + { + iterateSyncIO((x, y, z, b) -> palette.writeNode(b, dos)); + } } default void read(DataInputStream din) throws IOException { int w = getWidth(); int h = getHeight(); - MatterPalette palette = new MatterPalette(this, din); - int nodes = Varint.readUnsignedVarInt(din); - int[] pos; + if(din.readBoolean()) + { + int nodes = Varint.readUnsignedVarInt(din); + int[] pos; - while (nodes-- > 0) { - pos = Cache.to3D(Varint.readUnsignedVarInt(din), w, h); - setRaw(pos[0], pos[1], pos[2], palette.readNode(din)); + while (nodes-- > 0) { + pos = Cache.to3D(Varint.readUnsignedVarInt(din), w, h); + setRaw(pos[0], pos[1], pos[2], palette.readNode(din)); + } + } + + else + { + iterateSyncIO((x, y, z, b) -> setRaw(x, y, z, palette.readNode(din))); } } diff --git a/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java index 08907a686..6c53388ab 100644 --- a/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java @@ -38,12 +38,10 @@ public class BlockMatter extends RawMatter { public BlockMatter(int width, int height, int depth) { super(width, height, depth, BlockData.class); registerWriter(World.class, ((w, d, x, y, z) -> w.getBlockAt(x, y, z).setBlockData(d))); - registerWriter(ParallaxWorld.class, (w, d, x, y, z) -> w.setBlock(x, y, z, d)); registerReader(World.class, (w, x, y, z) -> { BlockData d = w.getBlockAt(x, y, z).getBlockData(); return d.getMaterial().isAir() ? null : d; }); - registerReader(ParallaxWorld.class, ParallaxAccess::getBlock); } @Override