mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-04-13 11:16:09 +00:00
Mantle & Debugging
This commit is contained in:
107
src/main/java/com/volmit/iris/util/mantle/Mantle.java
Normal file
107
src/main/java/com/volmit/iris/util/mantle/Mantle.java
Normal file
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<Long, MantleRegion> 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);
|
||||
}
|
||||
}
|
||||
112
src/main/java/com/volmit/iris/util/mantle/MantleChunk.java
Normal file
112
src/main/java/com/volmit/iris/util/mantle/MantleChunk.java
Normal file
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<MantleMatter> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
69
src/main/java/com/volmit/iris/util/mantle/MantleMatter.java
Normal file
69
src/main/java/com/volmit/iris/util/mantle/MantleMatter.java
Normal file
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<Class<?>, 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 <T> MatterSlice<T> createSlice(Class<T> 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<Class<?>, MatterSlice<?>> buildSlicers() {
|
||||
KMap<Class<?>, 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;
|
||||
}
|
||||
}
|
||||
107
src/main/java/com/volmit/iris/util/mantle/MantleRegion.java
Normal file
107
src/main/java/com/volmit/iris/util/mantle/MantleRegion.java
Normal file
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<MantleChunk> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<BlockData> {
|
||||
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());
|
||||
}
|
||||
}
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<T> extends AtomicHunk<T> implements MatterSlice<T> {
|
||||
@Getter
|
||||
private final Class<T> type;
|
||||
protected final KMap<Class<?>, MatterWriter<?, T>> writers;
|
||||
protected final KMap<Class<?>, MatterReader<?, T>> readers;
|
||||
|
||||
public RawMantleMatter(int width, int height, int depth, Class<T> type) {
|
||||
super(width, height, depth);
|
||||
writers = new KMap<>();
|
||||
readers = new KMap<>();
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
protected <W> void registerWriter(Class<W> mediumType, MatterWriter<W, T> injector) {
|
||||
writers.put(mediumType, injector);
|
||||
}
|
||||
|
||||
protected <W> void registerReader(Class<W> mediumType, MatterReader<W, T> injector) {
|
||||
readers.put(mediumType, injector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <W> MatterWriter<W, T> writeInto(Class<W> mediumType) {
|
||||
return (MatterWriter<W, T>) writers.get(mediumType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <W> MatterReader<W, T> readFrom(Class<W> mediumType) {
|
||||
return (MatterReader<W, T>) readers.get(mediumType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract void writeNode(T b, DataOutputStream dos) throws IOException;
|
||||
|
||||
@Override
|
||||
public abstract T readNode(DataInputStream din) throws IOException;
|
||||
}
|
||||
Reference in New Issue
Block a user